You've already forked fuse-utils
mirror of
https://git.code.sf.net/p/fuse-emulator/fuse-utils
synced 2025-12-08 09:42:18 +03:00
298 lines
8.6 KiB
C
298 lines
8.6 KiB
C
/* tzxlist.c: Produce a listing of the blocks in a .tzx file
|
|
Copyright (c) 2001-2002 Philip Kendall, Darren Salt
|
|
|
|
$Id$
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
Author contact information:
|
|
|
|
E-mail: pak21-fuse@srcf.ucam.org
|
|
Postal address: 15 Crescent Road, Wokingham, Berks, RG40 2DB, England
|
|
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
#include <libspectrum.h>
|
|
|
|
#include "utils.h"
|
|
|
|
#define DESCRIPTION_LENGTH 80
|
|
|
|
const char *progname;
|
|
|
|
static const char*
|
|
hardware_desc( int type, int id )
|
|
{
|
|
switch( type ) {
|
|
case 0:
|
|
switch( id ) {
|
|
case 0: return "16K Spectrum";
|
|
case 1: return "48K Spectrum/Spectrum +";
|
|
case 2: return "48K Spectrum (Issue 1)";
|
|
case 3: return "128K Spectrum";
|
|
case 4: return "Spectrum +2";
|
|
case 5: return "Spectrum +2A/+3";
|
|
default: return "Unknown machine";
|
|
}
|
|
case 3:
|
|
switch( id ) {
|
|
case 0: return "AY-3-8192";
|
|
default: return "Unknown sound device";
|
|
}
|
|
case 4:
|
|
switch( id ) {
|
|
case 0: return "Kempston joystick";
|
|
case 1: return "Cursor/Protek/AGF joystick";
|
|
case 2: return "Sinclair joystick (Left)";
|
|
case 3: return "Sinclair joystick (Right)";
|
|
case 4: return "Fuller joystick";
|
|
default: return "Unknown joystick";
|
|
}
|
|
default: return "Unknown type";
|
|
}
|
|
}
|
|
|
|
static int
|
|
process_tzx( char *filename )
|
|
{
|
|
int error;
|
|
|
|
unsigned char *buffer; size_t length;
|
|
libspectrum_tape *tape;
|
|
|
|
GSList *ptr;
|
|
|
|
size_t i;
|
|
|
|
error = mmap_file( filename, &buffer, &length ); if( error ) return error;
|
|
|
|
error = libspectrum_tape_alloc( &tape );
|
|
if( error != LIBSPECTRUM_ERROR_NONE ) {
|
|
munmap( buffer, length );
|
|
return 1;
|
|
}
|
|
|
|
error = libspectrum_tzx_read( tape, buffer, length );
|
|
if( error != LIBSPECTRUM_ERROR_NONE ) {
|
|
munmap( buffer, length );
|
|
libspectrum_tape_free( tape );
|
|
return error;
|
|
}
|
|
|
|
if( munmap( buffer, length ) == -1 ) {
|
|
fprintf( stderr, "%s: couldn't munmap `%s': %s\n", progname, filename,
|
|
strerror( errno ) );
|
|
return 1;
|
|
}
|
|
|
|
printf("Listing of `%s':\n\n", filename );
|
|
|
|
ptr = tape->blocks;
|
|
|
|
while( ptr ) {
|
|
libspectrum_tape_block *block = (libspectrum_tape_block*)ptr->data;
|
|
char description[ DESCRIPTION_LENGTH ];
|
|
|
|
error =
|
|
libspectrum_tape_block_description( description, DESCRIPTION_LENGTH,
|
|
block );
|
|
if( error ) return 1;
|
|
printf( "Block type 0x%02x (%s)\n", libspectrum_tape_block_type( block ),
|
|
description );
|
|
|
|
switch( libspectrum_tape_block_type( block ) ) {
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_ROM:
|
|
printf(" Data length: %ld bytes\n",
|
|
(unsigned long)libspectrum_tape_block_data_length( block ) );
|
|
printf(" Pause length: %d ms\n",
|
|
libspectrum_tape_block_pause( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_TURBO:
|
|
printf(" %ld pilot pulses of %d tstates\n",
|
|
(unsigned long)libspectrum_tape_block_pilot_pulses( block ),
|
|
libspectrum_tape_block_pilot_length( block ) );
|
|
printf(" Sync pulses of %d and %d tstates\n",
|
|
libspectrum_tape_block_sync1_length( block ),
|
|
libspectrum_tape_block_sync2_length( block ) );
|
|
/* Fall through */
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_PURE_DATA:
|
|
printf(" Data bits are %d (reset) and %d (set) tstates\n",
|
|
libspectrum_tape_block_bit0_length( block ),
|
|
libspectrum_tape_block_bit1_length( block ) );
|
|
printf(" Data length: %ld bytes (%ld bits in last byte used)\n",
|
|
(unsigned long)libspectrum_tape_block_data_length( block ),
|
|
(unsigned long)libspectrum_tape_block_bits_in_last_byte(block) );
|
|
printf(" Pause length: %d ms\n",
|
|
libspectrum_tape_block_pause( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_PURE_TONE:
|
|
printf(" %ld pulses of %ld tstates\n",
|
|
(unsigned long)libspectrum_tape_block_count( block ),
|
|
(unsigned long)libspectrum_tape_block_pulse_length( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_PULSES:
|
|
for( i=0; i < libspectrum_tape_block_count( block ); i++ )
|
|
printf(" Pulse %3ld: length %d tstates\n",
|
|
(unsigned long)i,
|
|
libspectrum_tape_block_pulse_lengths( block, i ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_RAW_DATA:
|
|
printf(" Length: %ld bytes\n", (unsigned long)
|
|
libspectrum_tape_block_data_length( block ) );
|
|
printf(" Bits in last byte: %ld\n",
|
|
(unsigned long)libspectrum_tape_block_bits_in_last_byte(block) );
|
|
printf(" Each bit is %d tstates\n",
|
|
libspectrum_tape_block_bit_length( block ) );
|
|
printf(" Pause length: %d ms\n",
|
|
libspectrum_tape_block_pause( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_PAUSE:
|
|
printf(" Length: %d ms\n", libspectrum_tape_block_pause( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_GROUP_START:
|
|
printf(" Name: %s\n", libspectrum_tape_block_text( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_GROUP_END:
|
|
case LIBSPECTRUM_TAPE_BLOCK_LOOP_END:
|
|
case LIBSPECTRUM_TAPE_BLOCK_STOP48:
|
|
/* Do nothing */
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_JUMP:
|
|
printf(" Offset: %d\n", libspectrum_tape_block_offset( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_LOOP_START:
|
|
printf(" Count: %lu\n",
|
|
(unsigned long)libspectrum_tape_block_count( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_SELECT:
|
|
for( i = 0; i < libspectrum_tape_block_count( block ); i++ ) {
|
|
printf(" Choice %2ld: Offset %d: %s\n", (unsigned long)i,
|
|
libspectrum_tape_block_offsets( block, i ),
|
|
libspectrum_tape_block_texts( block, i ) );
|
|
}
|
|
break;
|
|
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_MESSAGE:
|
|
printf(" Display for %d seconds\n",
|
|
libspectrum_tape_block_pause( block ) );
|
|
/* Fall through */
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_COMMENT:
|
|
printf(" Comment: %s\n", libspectrum_tape_block_text( block ) );
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_ARCHIVE_INFO:
|
|
for( i = 0; i < libspectrum_tape_block_count( block ); i++ ) {
|
|
printf(" ");
|
|
switch( libspectrum_tape_block_ids( block, i ) ) {
|
|
case 0: printf("Full Title:"); break;
|
|
case 1: printf(" Publisher:"); break;
|
|
case 2: printf(" Author:"); break;
|
|
case 3: printf(" Year:"); break;
|
|
case 4: printf(" Langugage:"); break;
|
|
case 5: printf(" Category:"); break;
|
|
case 6: printf(" Price:"); break;
|
|
case 7: printf(" Loader:"); break;
|
|
case 8: printf(" Origin:"); break;
|
|
case 255: printf(" Comment:"); break;
|
|
default: printf("(Unknown string): "); break;
|
|
}
|
|
printf(" %s\n", libspectrum_tape_block_texts( block, i ) );
|
|
}
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_HARDWARE:
|
|
for( i = 0; i < libspectrum_tape_block_count( block ); i++ ) {
|
|
printf( " %s: ",
|
|
hardware_desc( libspectrum_tape_block_types( block, i ),
|
|
libspectrum_tape_block_ids( block, i )
|
|
)
|
|
);
|
|
switch( libspectrum_tape_block_values( block, i ) ) {
|
|
case 0: printf("runs"); break;
|
|
case 1: printf("runs, using hardware"); break;
|
|
case 2: printf("runs, does not use hardware"); break;
|
|
case 3: printf("does not run"); break;
|
|
}
|
|
printf("\n");
|
|
}
|
|
break;
|
|
|
|
case LIBSPECTRUM_TAPE_BLOCK_CUSTOM:
|
|
printf( " Description: %s\n", libspectrum_tape_block_text( block ) );
|
|
printf( " Length: %ld bytes\n",
|
|
(unsigned long)libspectrum_tape_block_data_length( block ) );
|
|
break;
|
|
|
|
default:
|
|
printf(" (Sorry -- %s can't handle that kind of block. Skipping it)\n",
|
|
progname );
|
|
break;
|
|
}
|
|
|
|
ptr = ptr->next;
|
|
}
|
|
|
|
error = libspectrum_tape_free( tape );
|
|
if( error != LIBSPECTRUM_ERROR_NONE ) {
|
|
munmap( buffer, length );
|
|
return error;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
main( int argc, char **argv )
|
|
{
|
|
int ret = 0;
|
|
int arg = 0;
|
|
|
|
progname = argv[0];
|
|
|
|
if( argc < 2 ) {
|
|
fprintf( stderr, "%s: usage: %s <tzx files>...\n", progname, progname );
|
|
return 1;
|
|
}
|
|
|
|
while( ++arg < argc )
|
|
ret |= process_tzx( argv[arg] );
|
|
|
|
return ret;
|
|
}
|