From: <zu...@us...> - 2007-11-30 07:48:31
|
Revision: 3370 http://fuse-emulator.svn.sourceforge.net/fuse-emulator/?rev=3370&view=rev Author: zubzero Date: 2007-11-29 23:48:32 -0800 (Thu, 29 Nov 2007) Log Message: ----------- Add support for .spc, .sta and .ltp tape images (feature request #1764995). Modified Paths: -------------- trunk/libspectrum/hacking/ChangeLog trunk/libspectrum/internals.h trunk/libspectrum/libspectrum.c trunk/libspectrum/libspectrum.h.in trunk/libspectrum/tap.c trunk/libspectrum/tape.c Modified: trunk/libspectrum/hacking/ChangeLog =================================================================== --- trunk/libspectrum/hacking/ChangeLog 2007-11-30 07:29:17 UTC (rev 3369) +++ trunk/libspectrum/hacking/ChangeLog 2007-11-30 07:48:32 UTC (rev 3370) @@ -569,3 +569,6 @@ 20071130 libspectrum.c: free *new_filename instead of new_filename (Stuart). 20071130 plusd.c: enable DISCiPLE/+D snapshot support and add support for 128K DISCiPLE/+D snapshots (feature request #1764996) (Stuart). +20071130 internals.h,libspectrum.c,libspectrum.h.in,tap.c,tape.c: add support + for .spc, .sta and .ltp tape images (feature request #1764995) + (Stuart). Modified: trunk/libspectrum/internals.h =================================================================== --- trunk/libspectrum/internals.h 2007-11-30 07:29:17 UTC (rev 3369) +++ trunk/libspectrum/internals.h 2007-11-30 07:48:32 UTC (rev 3370) @@ -166,11 +166,11 @@ libspectrum_error internal_tap_read( libspectrum_tape *tape, const libspectrum_byte *buffer, - const size_t length ); + const size_t length, libspectrum_id_t type ); libspectrum_error internal_tap_write( libspectrum_byte **buffer, size_t *length, - libspectrum_tape *tape ); + libspectrum_tape *tape, libspectrum_id_t type ); libspectrum_error internal_tzx_read( libspectrum_tape *tape, const libspectrum_byte *buffer, Modified: trunk/libspectrum/libspectrum.c =================================================================== --- trunk/libspectrum/libspectrum.c 2007-11-30 07:29:17 UTC (rev 3369) +++ trunk/libspectrum/libspectrum.c 2007-11-30 07:48:32 UTC (rev 3370) @@ -487,6 +487,9 @@ { LIBSPECTRUM_ID_MICRODRIVE_MDR, "mdr", 3, NULL, 0, 0, 0 }, { LIBSPECTRUM_ID_TAPE_TAP, "tap", 3, "\x13\0\0", 0, 3, 1 }, + { LIBSPECTRUM_ID_TAPE_SPC, "spc", 3, "\x11\0\0", 0, 3, 1 }, + { LIBSPECTRUM_ID_TAPE_STA, "sta", 3, "\x11\0\0", 0, 3, 1 }, + { LIBSPECTRUM_ID_TAPE_LTP, "ltp", 3, "\x11\0\0", 0, 3, 1 }, { LIBSPECTRUM_ID_TAPE_TZX, "tzx", 3, "ZXTape!", 0, 7, 4 }, { LIBSPECTRUM_ID_TAPE_WARAJEVO, "tap", 2, "\xff\xff\xff\xff", 8, 4, 2 }, @@ -650,6 +653,9 @@ *libspectrum_class = LIBSPECTRUM_CLASS_SNAPSHOT; return 0; case LIBSPECTRUM_ID_TAPE_TAP: + case LIBSPECTRUM_ID_TAPE_SPC: + case LIBSPECTRUM_ID_TAPE_STA: + case LIBSPECTRUM_ID_TAPE_LTP: case LIBSPECTRUM_ID_TAPE_TZX: case LIBSPECTRUM_ID_TAPE_WARAJEVO: case LIBSPECTRUM_ID_TAPE_Z80EM: Modified: trunk/libspectrum/libspectrum.h.in =================================================================== --- trunk/libspectrum/libspectrum.h.in 2007-11-30 07:29:17 UTC (rev 3369) +++ trunk/libspectrum/libspectrum.h.in 2007-11-30 07:48:32 UTC (rev 3370) @@ -167,6 +167,9 @@ /* Below here, present only in x.x.x and later */ LIBSPECTRUM_ID_TAPE_WAV, /* .wav tape image */ + LIBSPECTRUM_ID_TAPE_SPC, /* SP-style .spc tape image */ + LIBSPECTRUM_ID_TAPE_STA, /* Speculator-style .sta tape image */ + LIBSPECTRUM_ID_TAPE_LTP, /* Nuclear ZX-style .ltp tape image */ LIBSPECTRUM_ID_COMPRESSED_XFD, /* xfdmaster (Amiga) compressed file */ LIBSPECTRUM_ID_DISK_IMG, /* .img +D disk image */ LIBSPECTRUM_ID_DISK_MGT, /* .mgt +D disk image */ Modified: trunk/libspectrum/tap.c =================================================================== --- trunk/libspectrum/tap.c 2007-11-30 07:29:17 UTC (rev 3369) +++ trunk/libspectrum/tap.c 2007-11-30 07:48:32 UTC (rev 3370) @@ -34,27 +34,29 @@ static libspectrum_error write_rom( libspectrum_tape_block *block, libspectrum_byte **buffer, - libspectrum_byte **ptr, size_t *length ); + libspectrum_byte **ptr, size_t *length, libspectrum_id_t type ); static libspectrum_error write_turbo( libspectrum_tape_block *block, libspectrum_byte **buffer, - libspectrum_byte **ptr, size_t *length ); + libspectrum_byte **ptr, size_t *length, libspectrum_id_t type ); static libspectrum_error write_pure_data( libspectrum_tape_block *block, libspectrum_byte **buffer, - libspectrum_byte **ptr, size_t *length ); + libspectrum_byte **ptr, size_t *length, + libspectrum_id_t type ); static libspectrum_error write_tap_block( libspectrum_byte **buffer, libspectrum_byte **ptr, - size_t *length, libspectrum_byte *data, size_t data_length ); + size_t *length, libspectrum_byte *data, size_t data_length, + libspectrum_id_t type ); static libspectrum_error skip_block( libspectrum_tape_block *block, const char *message ); libspectrum_error internal_tap_read( libspectrum_tape *tape, const libspectrum_byte *buffer, - const size_t length ) + const size_t length, libspectrum_id_t type ) { libspectrum_tape_block *block; libspectrum_error error; - size_t data_length; libspectrum_byte *data; + size_t data_length, buf_length; libspectrum_byte *data; const libspectrum_byte *ptr, *end; @@ -79,11 +81,20 @@ /* Get the length, and move along the buffer */ data_length = ptr[0] + ptr[1] * 0x100; + if( type == LIBSPECTRUM_ID_TAPE_SPC || + type == LIBSPECTRUM_ID_TAPE_STA || + type == LIBSPECTRUM_ID_TAPE_LTP ) + data_length += 2; libspectrum_tape_block_set_data_length( block, data_length ); ptr += 2; + if( type == LIBSPECTRUM_ID_TAPE_STA ) + buf_length = data_length - 1; + else + buf_length = data_length; + /* Have we got enough bytes left in buffer? */ - if( end - ptr < (ptrdiff_t)data_length ) { + if( end - ptr < (ptrdiff_t)buf_length ) { libspectrum_tape_clear( tape ); free( block ); libspectrum_print_error( @@ -104,9 +115,26 @@ } libspectrum_tape_block_set_data( block, data ); - /* Copy the block data across, and move along */ - memcpy( data, ptr, data_length ); ptr += data_length; + /* Copy the block data across */ + memcpy( data, ptr, buf_length ); + /* Fix the parity byte for the SPC and STA tape formats */ + if( type == LIBSPECTRUM_ID_TAPE_SPC ) { + data[ data_length - 1 ] ^= data[0]; + } else if( type == LIBSPECTRUM_ID_TAPE_STA ) { + libspectrum_byte parity; + size_t i; + + parity = 0x00; + for( i = 0; i < data_length - 1; i++ ) { + parity ^= data[i]; + } + data[ data_length - 1 ] = parity; + } + + /* Move along the buffer */ + ptr += buf_length; + /* Give a 1s pause after each block */ libspectrum_tape_block_set_pause( block, 1000 ); @@ -123,12 +151,12 @@ libspectrum_tap_read( libspectrum_tape *tape, const libspectrum_byte *buffer, const size_t length ) { - return internal_tap_read( tape, buffer, length ); + return internal_tap_read( tape, buffer, length, LIBSPECTRUM_ID_TAPE_TAP ); } libspectrum_error internal_tap_write( libspectrum_byte **buffer, size_t *length, - libspectrum_tape *tape ) + libspectrum_tape *tape, libspectrum_id_t type ) { libspectrum_tape_iterator iterator; libspectrum_tape_block *block; @@ -145,19 +173,19 @@ switch( libspectrum_tape_block_type( block ) ) { case LIBSPECTRUM_TAPE_BLOCK_ROM: - error = write_rom( block, buffer, &ptr, length ); + error = write_rom( block, buffer, &ptr, length, type ); if( error != LIBSPECTRUM_ERROR_NONE ) { free( *buffer ); return error; } done = 1; break; case LIBSPECTRUM_TAPE_BLOCK_TURBO: - error = write_turbo( block, buffer, &ptr, length ); + error = write_turbo( block, buffer, &ptr, length, type ); if( error != LIBSPECTRUM_ERROR_NONE ) { free( *buffer ); return error; } done = 1; break; case LIBSPECTRUM_TAPE_BLOCK_PURE_DATA: - error = write_pure_data( block, buffer, &ptr, length ); + error = write_pure_data( block, buffer, &ptr, length, type ); if( error != LIBSPECTRUM_ERROR_NONE ) { free( *buffer ); return error; } done = 1; break; @@ -219,18 +247,18 @@ libspectrum_tap_write( libspectrum_byte **buffer, size_t *length, libspectrum_tape *tape ) { - return internal_tap_write( buffer, length, tape ); + return internal_tap_write( buffer, length, tape, LIBSPECTRUM_ID_TAPE_TAP ); } static libspectrum_error write_rom( libspectrum_tape_block *block, libspectrum_byte **buffer, - libspectrum_byte **ptr, size_t *length ) + libspectrum_byte **ptr, size_t *length, libspectrum_id_t type ) { libspectrum_error error; error = write_tap_block( buffer, ptr, length, libspectrum_tape_block_data( block ), - libspectrum_tape_block_data_length( block ) ); + libspectrum_tape_block_data_length( block ), type ); if( error != LIBSPECTRUM_ERROR_NONE ) return error; return LIBSPECTRUM_ERROR_NONE; @@ -238,7 +266,7 @@ static libspectrum_error write_turbo( libspectrum_tape_block *block, libspectrum_byte **buffer, - libspectrum_byte **ptr, size_t *length ) + libspectrum_byte **ptr, size_t *length, libspectrum_id_t type ) { libspectrum_error error; @@ -250,7 +278,7 @@ error = write_tap_block( buffer, ptr, length, libspectrum_tape_block_data( block ), - libspectrum_tape_block_data_length( block ) ); + libspectrum_tape_block_data_length( block ), type ); if( error != LIBSPECTRUM_ERROR_NONE ) return error; return LIBSPECTRUM_ERROR_NONE; @@ -258,7 +286,8 @@ static libspectrum_error write_pure_data( libspectrum_tape_block *block, libspectrum_byte **buffer, - libspectrum_byte **ptr, size_t *length ) + libspectrum_byte **ptr, size_t *length, + libspectrum_id_t type ) { libspectrum_error error; @@ -270,7 +299,7 @@ error = write_tap_block( buffer, ptr, length, libspectrum_tape_block_data( block ), - libspectrum_tape_block_data_length( block ) ); + libspectrum_tape_block_data_length( block ), type ); if( error != LIBSPECTRUM_ERROR_NONE ) return error; return LIBSPECTRUM_ERROR_NONE; @@ -278,18 +307,43 @@ static libspectrum_error write_tap_block( libspectrum_byte **buffer, libspectrum_byte **ptr, - size_t *length, libspectrum_byte *data, size_t data_length ) + size_t *length, libspectrum_byte *data, size_t data_length, + libspectrum_id_t type ) { libspectrum_error error; + size_t buf_length; - error = libspectrum_make_room( buffer, 2 + data_length, ptr, length ); + /* Discard the parity byte for STA files */ + if( type == LIBSPECTRUM_ID_TAPE_STA ) + buf_length = data_length - 1; + else + buf_length = data_length; + + if( type == LIBSPECTRUM_ID_TAPE_SPC || + type == LIBSPECTRUM_ID_TAPE_STA || + type == LIBSPECTRUM_ID_TAPE_LTP ) { + if( data_length < 2 ) { + libspectrum_print_error( LIBSPECTRUM_ERROR_INVALID, + "write_tap_block: block too short" ); + return LIBSPECTRUM_ERROR_INVALID; + } + data_length -= 2; + } + + error = libspectrum_make_room( buffer, 2 + buf_length, ptr, length ); if( error != LIBSPECTRUM_ERROR_NONE ) return error; /* Write out the length and the data */ *(*ptr)++ = data_length & 0x00ff; *(*ptr)++ = ( data_length & 0xff00 ) >> 8; - memcpy( *ptr, data, data_length ); (*ptr) += data_length; + memcpy( *ptr, data, buf_length ); + + /* Fix the parity for SPC files */ + if( type == LIBSPECTRUM_ID_TAPE_SPC ) + (*ptr)[ buf_length - 1 ] ^= (*ptr)[0]; + (*ptr) += buf_length; + return LIBSPECTRUM_ERROR_NONE; } Modified: trunk/libspectrum/tape.c =================================================================== --- trunk/libspectrum/tape.c 2007-11-30 07:29:17 UTC (rev 3369) +++ trunk/libspectrum/tape.c 2007-11-30 07:48:32 UTC (rev 3370) @@ -212,7 +212,10 @@ switch( type ) { case LIBSPECTRUM_ID_TAPE_TAP: - error = internal_tap_read( tape, buffer, length ); break; + case LIBSPECTRUM_ID_TAPE_SPC: + case LIBSPECTRUM_ID_TAPE_STA: + case LIBSPECTRUM_ID_TAPE_LTP: + error = internal_tap_read( tape, buffer, length, type ); break; case LIBSPECTRUM_ID_TAPE_TZX: error = internal_tzx_read( tape, buffer, length ); break; @@ -271,7 +274,10 @@ switch( type ) { case LIBSPECTRUM_ID_TAPE_TAP: - return internal_tap_write( buffer, length, tape ); + case LIBSPECTRUM_ID_TAPE_SPC: + case LIBSPECTRUM_ID_TAPE_STA: + case LIBSPECTRUM_ID_TAPE_LTP: + return internal_tap_write( buffer, length, tape, type ); case LIBSPECTRUM_ID_TAPE_TZX: return internal_tzx_write( buffer, length, tape ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |