From: <pa...@us...> - 2008-09-11 11:23:13
|
Revision: 3771 http://fuse-emulator.svn.sourceforge.net/fuse-emulator/?rev=3771&view=rev Author: pak21 Date: 2008-09-11 11:23:17 +0000 (Thu, 11 Sep 2008) Log Message: ----------- Add function to get block length. Modified Paths: -------------- trunk/libspectrum/hacking/ChangeLog trunk/libspectrum/internals.h trunk/libspectrum/libspectrum.c trunk/libspectrum/libspectrum.h.in trunk/libspectrum/tape_block.c trunk/libspectrum/test/test.c Modified: trunk/libspectrum/hacking/ChangeLog =================================================================== --- trunk/libspectrum/hacking/ChangeLog 2008-09-11 03:47:01 UTC (rev 3770) +++ trunk/libspectrum/hacking/ChangeLog 2008-09-11 11:23:17 UTC (rev 3771) @@ -673,3 +673,5 @@ 20080717 make-perl.c,libspectrum.h.in: Win32: fix functions export for dll (Marek). 20080821 sna.c: make 128Kb SNA files actually loadable again. +20080911 internals.h,libspectrum.{c,h.in},tape_block.c,test/test.c: add + function to get block length. Modified: trunk/libspectrum/internals.h =================================================================== --- trunk/libspectrum/internals.h 2008-09-11 03:47:01 UTC (rev 3770) +++ trunk/libspectrum/internals.h 2008-09-11 11:23:17 UTC (rev 3771) @@ -163,6 +163,8 @@ libspectrum_tape_generalised_data_symbol_table *table, const libspectrum_byte **ptr, size_t length ); +void libspectrum_init_bits_set( void ); + /* Format specific tape routines */ libspectrum_error Modified: trunk/libspectrum/libspectrum.c =================================================================== --- trunk/libspectrum/libspectrum.c 2008-09-11 03:47:01 UTC (rev 3770) +++ trunk/libspectrum/libspectrum.c 2008-09-11 11:23:17 UTC (rev 3771) @@ -116,6 +116,8 @@ #endif /* #ifdef HAVE_GCRYPT_H */ + libspectrum_init_bits_set(); + return LIBSPECTRUM_ERROR_NONE; } Modified: trunk/libspectrum/libspectrum.h.in =================================================================== --- trunk/libspectrum/libspectrum.h.in 2008-09-11 03:47:01 UTC (rev 3770) +++ trunk/libspectrum/libspectrum.h.in 2008-09-11 11:23:17 UTC (rev 3771) @@ -564,6 +564,9 @@ int WIN32_DLL libspectrum_tape_block_metadata( libspectrum_tape_block *block ); +libspectrum_dword +libspectrum_tape_block_length( libspectrum_tape_block *block ); + /* Accessor functions */ LIBSPECTRUM_TAPE_ACCESSORS Modified: trunk/libspectrum/tape_block.c =================================================================== --- trunk/libspectrum/tape_block.c 2008-09-11 03:47:01 UTC (rev 3770) +++ trunk/libspectrum/tape_block.c 2008-09-11 11:23:17 UTC (rev 3771) @@ -438,3 +438,117 @@ } } +/* Give the length of a tape block */ + +static int bits_set[ 256 ]; + +void +libspectrum_init_bits_set( void ) +{ + int i, j; + + /* Not big or clever, but easy to understand */ + + for( i = 0; i < 256; i++ ) { + int data = i; + bits_set[ i ] = 0; + for( j = 0; j < 8; j++ ) { + if( data & 0x01 ) bits_set[ i ]++; + data >>= 1; + } + } +} + +static libspectrum_dword +rom_block_length( libspectrum_tape_rom_block *rom ) +{ + libspectrum_dword length = ( rom->pause * 69888 ) / 20; + size_t i; + + for( i = 0; i < rom->length; i++ ) { + libspectrum_byte data = rom->data[ i ]; + length += ( 2 * 1710 ) * bits_set[ data ] + ( 2 * 855 ) * ( 8 - bits_set[ data ] ); + } + + return length; +} + +static libspectrum_dword +turbo_block_length( libspectrum_tape_turbo_block *turbo ) +{ + libspectrum_dword length = + turbo->pilot_pulses * turbo->pilot_length + + turbo->sync1_length + turbo->sync2_length + + ( turbo->pause * 69888 ) / 20; + size_t i; + + /* FIXME: needs to handle bits in last byte correctly */ + for( i = 0; i < turbo->length; i++ ) { + libspectrum_byte data = turbo->data[ i ]; + length += ( 2 * turbo->bit1_length ) * bits_set[ data ] + ( 2 * turbo->bit0_length ) * ( 8 - bits_set[ data ] ); + } + + return length; +} + +static libspectrum_dword +pulses_block_length( libspectrum_tape_pulses_block *pulses ) +{ + libspectrum_dword length = 0; + size_t i; + + for( i = 0; i < pulses->count; i++ ) length += pulses->lengths[ i ]; + + return length; +} + +static libspectrum_dword +pure_data_block_length( libspectrum_tape_pure_data_block *pure_data ) +{ + libspectrum_dword length = ( pure_data->pause * 69888 ) / 20; + size_t i; + + /* FIXME: needs to handle bits in last byte correctly */ + for( i = 0; i < pure_data->length; i++ ) { + libspectrum_byte data = pure_data->data[ i ]; + length += ( 2 * pure_data->bit1_length ) * bits_set[ data ] + ( 2 * pure_data->bit0_length ) * ( 8 - bits_set[ data ] ); + } + + return length; +} + +libspectrum_dword +libspectrum_tape_block_length( libspectrum_tape_block *block ) +{ + libspectrum_tape_pure_tone_block *pure_tone; + + switch( block->type ) { + case LIBSPECTRUM_TAPE_BLOCK_ROM: + return rom_block_length( &block->types.rom ); + case LIBSPECTRUM_TAPE_BLOCK_TURBO: + return turbo_block_length( &block->types.turbo ); + case LIBSPECTRUM_TAPE_BLOCK_PURE_TONE: + pure_tone = &block->types.pure_tone; + return pure_tone->pulses * pure_tone->length; + case LIBSPECTRUM_TAPE_BLOCK_PULSES: + return pulses_block_length( &block->types.pulses ); + case LIBSPECTRUM_TAPE_BLOCK_PURE_DATA: + return pure_data_block_length( &block->types.pure_data ); + case LIBSPECTRUM_TAPE_BLOCK_PAUSE: + return ( block->types.pause.length * 69888 ) / 20; + case LIBSPECTRUM_TAPE_BLOCK_GROUP_START: + case LIBSPECTRUM_TAPE_BLOCK_GROUP_END: + case LIBSPECTRUM_TAPE_BLOCK_JUMP: + case LIBSPECTRUM_TAPE_BLOCK_LOOP_START: + case LIBSPECTRUM_TAPE_BLOCK_LOOP_END: + case LIBSPECTRUM_TAPE_BLOCK_STOP48: + case LIBSPECTRUM_TAPE_BLOCK_COMMENT: + case LIBSPECTRUM_TAPE_BLOCK_MESSAGE: + case LIBSPECTRUM_TAPE_BLOCK_ARCHIVE_INFO: + case LIBSPECTRUM_TAPE_BLOCK_HARDWARE: + case LIBSPECTRUM_TAPE_BLOCK_CUSTOM: + return 0; + default: + return -1; + } +} Modified: trunk/libspectrum/test/test.c =================================================================== --- trunk/libspectrum/test/test.c 2008-09-11 03:47:01 UTC (rev 3770) +++ trunk/libspectrum/test/test.c 2008-09-11 11:23:17 UTC (rev 3771) @@ -493,6 +493,75 @@ return r; } +static test_return_t +test_24( void ) +{ + const char *filename = DYNAMIC_TEST_PATH( "complete-tzx.tzx" ); + libspectrum_byte *buffer; + size_t filesize; + libspectrum_tape *tape; + libspectrum_tape_iterator it; + libspectrum_tape_block *block; + libspectrum_dword expected_sizes[20] = { + 8214888, /* ROM */ + 3494155, /* Turbo */ + 356310, /* Pure tone */ + 1761, /* Pulses */ + 1992829, /* Pure data */ + 2159539, /* Pause */ + 0, /* Group start */ + 0, /* Group end */ + 0, /* Jump */ + 205434, /* Pure tone */ + 0, /* Loop start */ + 154845, /* Pure tone */ + 0, /* Loop end */ + 0, /* Stop tape if in 48K mode */ + 0, /* Comment */ + 0, /* Message */ + 0, /* Archive info */ + 0, /* Hardware */ + 0, /* Custom info */ + 771620, /* Pure tone */ + }; + libspectrum_dword *next_size = &expected_sizes[ 0 ]; + test_return_t r = TEST_PASS; + + if( read_file( &buffer, &filesize, filename ) ) return TEST_INCOMPLETE; + + tape = libspectrum_tape_alloc(); + + if( libspectrum_tape_read( tape, buffer, filesize, LIBSPECTRUM_ID_UNKNOWN, + filename ) ) { + libspectrum_tape_free( tape ); + libspectrum_free( buffer ); + return TEST_INCOMPLETE; + } + + libspectrum_free( buffer ); + + block = libspectrum_tape_iterator_init( &it, tape ); + + while( block ) + { + libspectrum_dword actual_size = libspectrum_tape_block_length( block ); + + if( actual_size != *next_size ) + { + fprintf( stderr, "%s: block had length %lu, but expected %lu\n", progname, (unsigned long)actual_size, (unsigned long)*next_size ); + r = TEST_FAIL; + break; + } + + block = libspectrum_tape_iterator_next( &it ); + next_size++; + } + + if( libspectrum_tape_free( tape ) ) return TEST_INCOMPLETE; + + return r; +} + struct test_description { test_fn test; @@ -525,6 +594,7 @@ { test_21, "SNA file with SP = 0xffff", 0 }, { test_22, "MDR write protection 1", 0 }, { test_23, "MDR write protection 2", 0 }, + { test_24, "Complete TZX timings", 0 }, }; static size_t test_count = sizeof( tests ) / sizeof( tests[0] ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |