Exemplo n.º 1
0
static void
memory_pool_free_entry( gpointer data, gpointer user_data GCC_UNUSED )
{
  memory_pool_entry_t *entry = data;
  libspectrum_free( entry->memory );
  libspectrum_free( entry );
}
Exemplo n.º 2
0
/* Write the current in-memory tape file out to disk */
int tape_write( const char* filename )
{
  libspectrum_id_t type;
  libspectrum_class_t class;
  libspectrum_byte *buffer; size_t length;

  int error;

  /* Work out what sort of file we want from the filename; default to
     .tzx if we couldn't guess */
  error = libspectrum_identify_file_with_class( &type, &class, filename, NULL,
						0 );
  if( error ) return error;

  if( class != LIBSPECTRUM_CLASS_TAPE || type == LIBSPECTRUM_ID_UNKNOWN )
    type = LIBSPECTRUM_ID_TAPE_TZX;

  length = 0;

  error = libspectrum_tape_write( &buffer, &length, tape, type );
  if( error != LIBSPECTRUM_ERROR_NONE ) return error;

  error = utils_write_file( filename, buffer, length );
  if( error ) { libspectrum_free( buffer ); return error; }

  tape_modified = 0;
  ui_tape_browser_update( UI_TAPE_BROWSER_MODIFIED, NULL );

  libspectrum_free( buffer );

  return 0;
}
Exemplo n.º 3
0
int snapshot_write( const char *filename )
{
  libspectrum_id_t type;
  libspectrum_class_t class;
  libspectrum_snap *snap;
  unsigned char *buffer; size_t length;
  int flags;

  int error;

  /* Work out what sort of file we want from the filename; default to
     .szx if we couldn't guess */
  error = libspectrum_identify_file_with_class( &type, &class, filename, NULL,
						0 );
  if( error ) return error;

  if( class != LIBSPECTRUM_CLASS_SNAPSHOT || type == LIBSPECTRUM_ID_UNKNOWN )
    type = LIBSPECTRUM_ID_SNAPSHOT_SZX;

  snap = libspectrum_snap_alloc();

  error = snapshot_copy_to( snap );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  flags = 0;
  length = 0;
  buffer = NULL;
  error = libspectrum_snap_write( &buffer, &length, &flags, snap, type,
				  fuse_creator, 0 );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MAJOR_INFO_LOSS ) {
    ui_error(
      UI_ERROR_WARNING,
      "A large amount of information has been lost in conversion; the snapshot probably won't work"
    );
  } else if( flags & LIBSPECTRUM_FLAG_SNAPSHOT_MINOR_INFO_LOSS ) {
    ui_error(
      UI_ERROR_WARNING,
      "Some information has been lost in conversion; the snapshot may not work"
    );
  }

  error = libspectrum_snap_free( snap );
  if( error ) { libspectrum_free( buffer ); return 1; }

  error = utils_write_file( filename, buffer, length );
  if( error ) { libspectrum_free( buffer ); return error; }

  libspectrum_free( buffer );

  return 0;

}
Exemplo n.º 4
0
int
rzx_finalise_recording( const char *filename )
{
  libspectrum_byte *buffer; size_t length;
  libspectrum_error libspec_error; int error;
  utils_file file;

  if( rzx_recording || rzx_playback ) return 1;

  error = utils_read_file( filename, &file );
  if( error ) return error;

  rzx = libspectrum_rzx_alloc();

  libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) {
    utils_close_file( &file );
    libspectrum_rzx_free( rzx );
    return libspec_error;
  }

  utils_close_file( &file );

  libspec_error = libspectrum_rzx_finalise( rzx );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) {
    libspectrum_rzx_free( rzx );
    return libspec_error;
  }

  /* Write the file */
  length = 0;
  buffer = NULL;
  libspec_error = libspectrum_rzx_write(
    &buffer, &length, rzx, LIBSPECTRUM_ID_UNKNOWN, fuse_creator,
    settings_current.rzx_compression, rzx_competition_mode ? &rzx_key : NULL
  );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) {
    libspectrum_rzx_free( rzx );
    return libspec_error;
  }

  error = utils_write_file( filename, buffer, length );
  if( error ) {
    libspectrum_free( buffer );
    libspectrum_rzx_free( rzx );
    return error;
  }

  libspectrum_free( buffer );
  libspectrum_rzx_free( rzx );

  return 0;
}
Exemplo n.º 5
0
static libspectrum_error
rzx_read_frames( input_block_t *block, const libspectrum_byte **ptr,
		 const libspectrum_byte *end )
{
  size_t i, j;

  /* And read in the frames */
  for( i=0; i < block->count; i++ ) {

    /* Check the two length bytes exist */
    if( end - (*ptr) < 4 ) {
      libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			       "rzx_read_frames: not enough data in buffer" );
      for( j=0; j<i; j++ ) {
	if( !block->frames[i].repeat_last ) libspectrum_free( block->frames[j].in_bytes );
      }
      return LIBSPECTRUM_ERROR_CORRUPT;
    }

    block->frames[i].instructions = libspectrum_read_word( ptr );
    block->frames[i].count        = libspectrum_read_word( ptr );

    if( block->frames[i].count == libspectrum_rzx_repeat_frame ) {
      block->frames[i].repeat_last = 1;
      continue;
    }

    block->frames[i].repeat_last = 0;

    if( end - (*ptr) < (ptrdiff_t)block->frames[i].count ) {
      libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			       "rzx_read_frames: not enough data in buffer" );
      for( j=0; j<i; j++ ) {
	if( !block->frames[i].repeat_last ) libspectrum_free( block->frames[j].in_bytes );
      }
      return LIBSPECTRUM_ERROR_CORRUPT;
    }

    if( block->frames[i].count ) {

      block->frames[i].in_bytes =
	libspectrum_malloc( block->frames[i].count * sizeof( libspectrum_byte ) );
      memcpy( block->frames[i].in_bytes, *ptr, block->frames[i].count );

    } else {
      block->frames[i].in_bytes = NULL;
    }

    (*ptr) += block->frames[i].count;
  }

  return LIBSPECTRUM_ERROR_NONE;
}
Exemplo n.º 6
0
static void
machine_end( void )
{
  int i;

  for( i=0; i<machine_count; i++ ) {
    if( machine_types[i]->shutdown ) machine_types[i]->shutdown();
    libspectrum_free( machine_types[i] );
  }

  libspectrum_free( machine_types );
}
Exemplo n.º 7
0
static void
free_symbol_table( libspectrum_tape_generalised_data_symbol_table *table )
{
  size_t i;

  if( table->symbols ) {
    for( i = 0; i < table->symbols_in_table; i++ )
      libspectrum_free( table->symbols[ i ].lengths );

    libspectrum_free( table->symbols );
  }
}
Exemplo n.º 8
0
int rzx_stop_recording( void )
{
  libspectrum_byte *buffer; size_t length;
  libspectrum_error libspec_error; int error;

  if( !rzx_recording ) return 0;

  /* Stop recording data */
  rzx_recording = 0;
  if( settings_current.movie_stop_after_rzx ) movie_stop();

  /* Embed final snapshot */
  if( !rzx_competition_mode ) rzx_add_snap( rzx, 0 );

  libspectrum_free( rzx_in_bytes );
  rzx_in_bytes = NULL;
  rzx_in_allocated = 0;

  ui_menu_activate( UI_MENU_ITEM_RECORDING, 0 );
  ui_menu_activate( UI_MENU_ITEM_RECORDING_ROLLBACK, 0 );

  libspectrum_creator_set_competition_code(
    fuse_creator, settings_current.competition_code
  );

  length = 0;
  buffer = NULL;
  libspec_error = libspectrum_rzx_write(
    &buffer, &length, rzx, LIBSPECTRUM_ID_UNKNOWN, fuse_creator,
    settings_current.rzx_compression, rzx_competition_mode ? &rzx_key : NULL
  );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) {
    libspectrum_free( rzx_filename );
    libspectrum_rzx_free( rzx );
    return libspec_error;
  }

  error = utils_write_file( rzx_filename, buffer, length );
  libspectrum_free( rzx_filename );
  if( error ) {
    libspectrum_free( buffer );
    libspectrum_rzx_free( rzx );
    return error;
  }

  libspectrum_free( buffer );

  libspec_error = libspectrum_rzx_free( rzx );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) return libspec_error;

  return 0;
}
Exemplo n.º 9
0
void
g_hash_table_destroy (GHashTable *hash_table)
{
  guint i;
  
  for (i = 0; i < HASH_TABLE_SIZE; i++)
    g_hash_nodes_destroy (hash_table->nodes[i],
                          hash_table->key_destroy_func,
                          hash_table->value_destroy_func);

  libspectrum_free (hash_table->nodes);
  libspectrum_free (hash_table);
}
Exemplo n.º 10
0
/* Free all non-persistent memory in the pool */
void
memory_pool_free( void )
{
  GSList *ptr;

  while( ( ptr = g_slist_find_custom( pool, NULL, find_non_persistent ) ) != NULL )
  {
    memory_pool_entry_t *entry = ptr->data;
    libspectrum_free( entry->memory );
    pool = g_slist_remove( pool, entry );
    libspectrum_free( entry );
  }
}
Exemplo n.º 11
0
static libspectrum_error
serialise_mpis( libspectrum_byte **signature, size_t *signature_length,
		gcry_mpi_t r, gcry_mpi_t s )
{
  gcry_error_t error;
  size_t length, length_s;
  unsigned char *ptr;

  error = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &length, r );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: length of r: %s",
			     gcry_strerror( error ) );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  error = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &length_s, s );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: length of s: %s",
			     gcry_strerror( error ) );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  length += length_s; *signature_length = length;

  *signature = libspectrum_malloc( length );

  error = gcry_mpi_print( GCRYMPI_FMT_PGP, *signature, length, &length, r );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: printing r: %s",
			     gcry_strerror( error ) );
    libspectrum_free( *signature );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  ptr = *signature + length; length = *signature_length - length;
  error = gcry_mpi_print( GCRYMPI_FMT_PGP, ptr, length, NULL, s );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "serialise_mpis: printing s: %s",
			     gcry_strerror( error ) );
    libspectrum_free( *signature );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  return LIBSPECTRUM_ERROR_NONE;
}
Exemplo n.º 12
0
int
ide_eject( libspectrum_ide_channel *chn, libspectrum_ide_unit unit,
	   int (*commit_fn)( libspectrum_ide_unit unit ), char **setting,
	   ui_menu_item item )
{
  int error;

  if( libspectrum_ide_dirty( chn, unit ) ) {
    
    ui_confirm_save_t confirm = ui_confirm_save(
      "Hard disk has been modified.\nDo you want to save it?"
    );
  
    switch( confirm ) {

    case UI_CONFIRM_SAVE_SAVE:
      error = commit_fn( unit ); if( error ) return error;
      break;

    case UI_CONFIRM_SAVE_DONTSAVE: break;
    case UI_CONFIRM_SAVE_CANCEL: return 1;

    }
  }

  libspectrum_free( *setting ); *setting = NULL;
  
  error = libspectrum_ide_eject( chn, unit );
  if( error ) return error;

  error = ui_menu_activate( item, 0 );
  if( error ) return error;

  return 0;
}
Exemplo n.º 13
0
void
sound_end( void )
{
  if( sound_enabled ) {
    delete_Blip_Synth( &left_beeper_synth );
    delete_Blip_Synth( &right_beeper_synth );

    delete_Blip_Synth( &ay_a_synth );
    delete_Blip_Synth( &ay_b_synth );
    delete_Blip_Synth( &ay_c_synth );
    delete_Blip_Synth( &ay_a_synth_r );
    delete_Blip_Synth( &ay_b_synth_r );
    delete_Blip_Synth( &ay_c_synth_r );

    delete_Blip_Synth( &left_specdrum_synth );
    delete_Blip_Synth( &right_specdrum_synth );

    delete_Blip_Buffer( &left_buf );
    delete_Blip_Buffer( &right_buf );

    if( settings_current.sound ) 
      sound_lowlevel_end();
    libspectrum_free( samples );
    sound_enabled = 0;
  }
}
Exemplo n.º 14
0
int rzx_start_recording( const char *filename, int embed_snapshot )
{
  int error;

  if( rzx_playback ) return 1;

  rzx = libspectrum_rzx_alloc();

  /* Store the filename */
  rzx_filename = utils_safe_strdup( filename );

  /* If we're embedding a snapshot, create it now */
  if( embed_snapshot ) {
    error = rzx_add_snap( rzx, 0 );

    if( error ) {
      libspectrum_free( rzx_filename );
      libspectrum_rzx_free( rzx );
      return error;
    }
  }

  start_recording( rzx, settings_current.competition_mode );

  return 0;
}
Exemplo n.º 15
0
void
libspectrum_hashtable_cleanup( void )
{
  libspectrum_free( node_allocated_list );
  node_allocated_list = NULL;
  node_free_list = NULL;
}
Exemplo n.º 16
0
gchar*
g_array_free( GArray *array, gboolean free_segment )
{
  gchar* segment;

  if( free_segment ) {
    libspectrum_free( array->data );
    segment = NULL;
  }
  else
    segment = array->data;

  libspectrum_free( array );

  return segment;
}
Exemplo n.º 17
0
static libspectrum_error
rzx_write_signed_end( libspectrum_byte **buffer, libspectrum_byte **ptr,
		      size_t *length, ptrdiff_t sign_offset,
		      libspectrum_rzx_dsa_key *key )
{
#ifdef HAVE_GCRYPT_H
  libspectrum_error error;
  libspectrum_byte *signature; size_t sig_length;

  /* Get the actual signature */
  error = libspectrum_sign_data( &signature, &sig_length,
				 ( *buffer + sign_offset ),
				 (*ptr) - ( *buffer + sign_offset ), key );
  if( error ) return error;

  libspectrum_make_room( buffer, sig_length + 5, ptr, length );

  /* Block ID */
  *(*ptr)++ = LIBSPECTRUM_RZX_SIGN_END_BLOCK;

  /* Block length */
  libspectrum_write_dword( ptr, sig_length + 5 );

  /* Write the signature */
  memcpy( *ptr, signature, sig_length ); (*ptr) += sig_length;

  libspectrum_free( signature );

#endif				/* #ifdef HAVE_GCRYPT_H */

  return LIBSPECTRUM_ERROR_NONE;
}
Exemplo n.º 18
0
int
ui_mdr_write( int which, int saveas )
{
    int err;
    char *filename = NULL, title[80];

    fuse_emulation_pause();

    snprintf( title, 80, "Fuse - Write Microdrive Cartridge %i", which + 1 );

    if( saveas ) {
        filename = ui_get_save_filename( title );
        if( !filename ) {
            fuse_emulation_unpause();
            return 1;
        }
    }

    err = if1_mdr_write( which, filename );

    if( saveas ) libspectrum_free( filename );

    fuse_emulation_unpause();

    return err;
}
Exemplo n.º 19
0
libspectrum_error
libspectrum_rzx_free( libspectrum_rzx *rzx )
{
  g_slist_foreach( rzx->blocks, block_free_wrapper, NULL );
  g_slist_free( rzx->blocks );
  libspectrum_free( rzx );

  return LIBSPECTRUM_ERROR_NONE;
}
Exemplo n.º 20
0
static libspectrum_error
get_hash( gcry_sexp_t *hash, const libspectrum_byte *data, size_t data_length )
{
  gcry_error_t error;
  unsigned char *digest; size_t digest_length;
  gcry_mpi_t hash_mpi;
  
  digest_length = gcry_md_get_algo_dlen( HASH_ALGORITHM );
  digest = libspectrum_malloc( digest_length );

  gcry_md_hash_buffer( HASH_ALGORITHM, digest, data, data_length );

  error = gcry_mpi_scan( &hash_mpi, GCRYMPI_FMT_USG, digest, digest_length,
			 NULL );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "get_hash: error creating hash MPI: %s",
			     gcry_strerror( error )
    );
    libspectrum_free( digest );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  libspectrum_free( digest );

  error = gcry_sexp_build( hash, NULL, hash_format, hash_mpi );
  if( error ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			     "get_hash: error creating hash sexp: %s",
			     gcry_strerror( error )
    );
    gcry_mpi_release( hash_mpi );
    return LIBSPECTRUM_ERROR_LOGIC;
  }

  gcry_mpi_release( hash_mpi );

  return LIBSPECTRUM_ERROR_NONE;
}
Exemplo n.º 21
0
/* Request a snapshot file from the user and it */
int
utils_open_snap( void )
{
  char *filename;
  int error;

  filename = ui_get_open_filename( "Fuse - Load Snapshot" );
  if( !filename ) return -1;

  error = snapshot_read( filename );
  libspectrum_free( filename );
  return error;
}
Exemplo n.º 22
0
int
display_init( int *argc, char ***argv )
{
  int i, j, k, x, y;
  int error;

  if(ui_init(argc, argv))
    return 1;

  /* Set up the 'all pixels must be refreshed' marker */
  display_all_dirty = 0;
  for( i = 0; i < DISPLAY_SCREEN_WIDTH_COLS; i++ )
    display_all_dirty = ( display_all_dirty << 1 ) | 0x01;

  for(i=0;i<3;i++)
    for(j=0;j<8;j++)
      for(k=0;k<8;k++)
	display_line_start[ (64*i) + (8*j) + k ] =
	  32 * ( (64*i) + j + (k*8) );

  for(y=0;y<DISPLAY_HEIGHT;y++) {
    display_attr_start[y]=6144 + (32*(y/8));
  }

  for(y=0;y<DISPLAY_HEIGHT;y++)
    for(x=0;x<DISPLAY_WIDTH_COLS;x++) {
      display_dirty_ytable[ display_line_start[y]+x ] = y;
      display_dirty_xtable[ display_line_start[y]+x ] = x;
    }

  for(y=0;y<DISPLAY_HEIGHT_ROWS;y++)
    for(x=0;x<DISPLAY_WIDTH_COLS;x++) {
      display_dirty_ytable2[ (32*y) + x ] = y * 8;
      display_dirty_xtable2[ (32*y) + x ] = x;
    }

  display_frame_count=0; display_flash_reversed=0;

  display_refresh_all();

  border_changes_last = 0;
  if( border_changes ) {
    libspectrum_free( border_changes );
  }
  border_changes = NULL;
  error = add_border_sentinel(); if( error ) return error;
  display_last_border = scld_last_dec.name.hires ?
                            display_hires_border : display_lores_border;

  return 0;
}
Exemplo n.º 23
0
int
utils_read_fd( compat_fd fd, const char *filename, utils_file *file )
{
  file->length = compat_file_get_length( fd );
  if( file->length == -1 ) return 1;

  file->buffer = libspectrum_new( unsigned char, file->length );

  if( compat_file_read( fd, file ) ) {
    libspectrum_free( file->buffer );
    compat_file_close( fd );
    return 1;
  }

  if( compat_file_close( fd ) ) {
    ui_error( UI_ERROR_ERROR, "Couldn't close '%s': %s", filename,
	      strerror( errno ) );
    libspectrum_free( file->buffer );
    return 1;
  }

  return 0;
}
Exemplo n.º 24
0
void
dck_eject( void )
{
  if ( !( libspectrum_machine_capabilities( machine_current->machine ) &
	  LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) {
    ui_error( UI_ERROR_ERROR, "This machine does not support the dock" );
    return;
  }

  if( settings_current.dck_file ) libspectrum_free( settings_current.dck_file );
  settings_current.dck_file = NULL;

  dck_active = 0;

  ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );

  machine_reset( 0 );
}
Exemplo n.º 25
0
int
rzx_continue_recording( const char *filename )
{
  utils_file file;
  libspectrum_error libspec_error; int error;
  libspectrum_snap* snap = NULL;
  libspectrum_rzx_iterator last_it = NULL;

  if( rzx_recording || rzx_playback ) return 1;

  /* Store the filename */
  rzx_filename = utils_safe_strdup( filename );

  error = utils_read_file( filename, &file );
  if( error ) return error;

  rzx = libspectrum_rzx_alloc();

  libspec_error = libspectrum_rzx_read( rzx, file.buffer, file.length );
  if( libspec_error != LIBSPECTRUM_ERROR_NONE ) {
    utils_close_file( &file );
    return libspec_error;
  }

  utils_close_file( &file );

  /* Get final snapshot */
  last_it = libspectrum_rzx_iterator_last( rzx );
  if( last_it ) snap = libspectrum_rzx_iterator_get_snap( last_it );

  if( snap ) {
    error = snapshot_copy_from( snap );
    if( error ) return error;
  } else {
    ui_error( UI_ERROR_WARNING, "RZX file cannot be continued" );
    libspectrum_free( rzx_filename );
    libspectrum_rzx_free( rzx );
    return 1;
  }

  start_recording( rzx, 0 );

  return 0;
}
Exemplo n.º 26
0
int
ui_tape_write( void )
{
    char *filename;

    fuse_emulation_pause();

    filename = ui_get_save_filename( "Fuse - Write Tape" );
    if( !filename ) {
        fuse_emulation_unpause();
        return 1;
    }

    tape_write( filename );

    libspectrum_free( filename );

    fuse_emulation_unpause();

    return 0;
}
Exemplo n.º 27
0
static libspectrum_error
block_free( rzx_block_t *block )
{
  size_t i;
  input_block_t *input;
#ifdef HAVE_GCRYPT_H
  signature_block_t *signature;
#endif				/* #ifdef HAVE_GCRYPT_H */

  switch( block->type ) {

  case LIBSPECTRUM_RZX_INPUT_BLOCK:
    input = &( block->types.input );
    for( i = 0; i < input->count; i++ )
      if( !input->frames[i].repeat_last ) libspectrum_free( input->frames[i].in_bytes );
    libspectrum_free( input->frames );
    libspectrum_free( block );
    return LIBSPECTRUM_ERROR_NONE;

  case LIBSPECTRUM_RZX_SNAPSHOT_BLOCK:
    libspectrum_snap_free( block->types.snap.snap );
    libspectrum_free( block );
    return LIBSPECTRUM_ERROR_NONE;

  case LIBSPECTRUM_RZX_SIGN_START_BLOCK:
    libspectrum_free( block );
    return LIBSPECTRUM_ERROR_NONE;

  case LIBSPECTRUM_RZX_SIGN_END_BLOCK:
#ifdef HAVE_GCRYPT_H
    signature = &( block->types.signature );
    gcry_mpi_release( signature->r );
    gcry_mpi_release( signature->s );
#endif				/* #ifdef HAVE_GCRYPT_H */

    libspectrum_free( block );
    return LIBSPECTRUM_ERROR_NONE;

  case LIBSPECTRUM_RZX_CREATOR_BLOCK:
    break;

  }

  libspectrum_print_error( LIBSPECTRUM_ERROR_LOGIC,
			   "unknown RZX block type %d at %s:%d", block->type,
			   __FILE__, __LINE__ );
  return LIBSPECTRUM_ERROR_LOGIC;
}
Exemplo n.º 28
0
void
nic_w5100_free( nic_w5100_t *self )
{
  int i;

  if( self ) {
    self->stop_io_thread = 1;
    compat_socket_selfpipe_wake( self->selfpipe );

    pthread_join( self->thread, NULL );

    for( i = 0; i < 4; i++ )
      nic_w5100_socket_end( &self->socket[i] );

    compat_socket_selfpipe_free( self->selfpipe );

    compat_socket_networking_end();

    libspectrum_free( self );
  }
}
Exemplo n.º 29
0
/* Tidy-up function called at end of emulation */
static void
memory_end( void )
{
  int i;
  char *description;

  /* Free all the memory we've allocated for this machine */
  if( pool ) {
    g_slist_foreach( pool, memory_pool_free_entry, NULL );
    g_slist_free( pool );
    pool = NULL;
  }

  /* Free memory source types */
  if( memory_sources ) {
    for( i = 0; i < memory_sources->len; i++ ) {
      description = g_array_index( memory_sources, char *, i );
      libspectrum_free( description );
    }

    g_array_free( memory_sources, TRUE );
    memory_sources = NULL;
  }
}
Exemplo n.º 30
0
static libspectrum_error
inflate_block( libspectrum_byte **uncompressed, size_t *uncompressed_length,
	       const libspectrum_byte **compressed, size_t compressed_length )
{

#ifdef HAVE_ZLIB_H

  libspectrum_dword header_length, expected_crc32, actual_crc32;
  libspectrum_byte *zlib_buffer;
  unsigned long actual_length;
  int error;

  /* First, look at the compression header */
  header_length = libspectrum_read_dword( compressed );
  if( header_length != 12 ) {
    libspectrum_print_error( LIBSPECTRUM_ERROR_UNKNOWN,
			     "zxs_inflate_block: unknown header length %lu",
			     (unsigned long)header_length );
    return LIBSPECTRUM_ERROR_UNKNOWN;
  }
  compressed_length -= 12;

  expected_crc32 = libspectrum_read_dword( compressed );
  *uncompressed_length = libspectrum_read_dword( compressed );

  /* Some space to put the zlib header for decompression */
  zlib_buffer =
    libspectrum_malloc( ( compressed_length + 6 ) * sizeof( *zlib_buffer ) );

  /* zlib's header */
  zlib_buffer[0] = 0x78; zlib_buffer[1] = 0xda;

  memcpy( &zlib_buffer[2], *compressed, compressed_length );
  *compressed += compressed_length;

  *uncompressed = libspectrum_malloc( *uncompressed_length * sizeof( **uncompressed ) );

  actual_length = *uncompressed_length;
  error = uncompress( *uncompressed, &actual_length, zlib_buffer,
		      compressed_length + 6 );

  /* At this point, we expect to get a Z_DATA_ERROR, as we don't have
     the Adler-32 checksum of the data. There is a 1 in 65521 chance
     that the random bytes will match, so we might (very rarely) get
     Z_OK */
  if( error != Z_DATA_ERROR && error != Z_OK ) {
    libspectrum_free( *uncompressed ); libspectrum_free( zlib_buffer );
    libspectrum_print_error( LIBSPECTRUM_ERROR_CORRUPT,
			     "zxs_inflate_block: unexpected zlib error" );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  if( *uncompressed_length != actual_length ) {
    libspectrum_free( *uncompressed ); libspectrum_free( zlib_buffer );
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_CORRUPT,
      "zxs_inflate_block: block expanded to 0x%04lx, not the expected 0x%04lx bytes",
      actual_length, (unsigned long)*uncompressed_length
    );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  libspectrum_free( zlib_buffer );

  actual_crc32 = crc32( 0, Z_NULL, 0 );
  actual_crc32 = crc32( actual_crc32, *uncompressed, *uncompressed_length );

  if( actual_crc32 != expected_crc32 ) {
    libspectrum_free( *uncompressed );
    libspectrum_print_error(
      LIBSPECTRUM_ERROR_CORRUPT,
      "zxs_inflate_block: crc 0x%08x does not match expected 0x%08x",
      actual_crc32, expected_crc32
    );
    return LIBSPECTRUM_ERROR_CORRUPT;
  }

  return LIBSPECTRUM_ERROR_NONE;

#else				/* #ifdef HAVE_ZLIB_H */

  /* No zlib, so can't inflate the block */
  return LIBSPECTRUM_ERROR_UNKNOWN;

#endif				/* #ifdef HAVE_ZLIB_H */

}