Пример #1
0
int shader_program_file_create(shader_program_file_t *pfile, const char *filename)
{
	char *buffer = NULL;
	long file_size = 0L;
	
	IF_FAILED0(pfile && filename);
	
	TRACE_MSG("create shader program file; filename = %s \n", filename);
	
	file_size = utils_file_get_size(filename);
	// file_size + 1 - чтобы хватило места для \0
	buffer = (char*) malloc(sizeof(char) * (file_size+1));
	
	if(!utils_read_file(filename, buffer)) {
		ERROR_MSG("cannot open shader program file\n");
		return 0;
	}
	
	if(!parse_and_load_shader(buffer, pfile))
		return 0;
	
	free(buffer);
	
	return 1;
}
Пример #2
0
int
main( int argc, char **argv )
{
  char *buffer; size_t length;
  struct program *basic_program;
  int error;

  progname = argv[0];

  if( argc < 2 ) {
    fprintf( stderr, "%s: usage: %s <basic file>\n", progname, progname );
    return 1;
  }

  error = utils_read_file( &buffer, &length, argv[1] );
  if( error ) return error;

  basic_program = parse_program( buffer, length );
  if( !basic_program ) return 1;

  free( buffer );

  error = interpret_program( basic_program );
  if( error ) { program_free( basic_program ); return error; }

  if( program_free( basic_program ) ) {
    fprintf( stderr, "%s: error freeing program\n", progname );
    return 1;
  }

  return 0;
}
Пример #3
0
void
menu_file_loadbinarydata( int action )
{
  /* FIXME: a way to associate a long type with a window is via SetWindowLong
            with GWL_USERDATA parameter - review past code and implement */
  
  struct binary_info info;

  int error;

  fuse_emulation_pause();

  info.dialog_title = TEXT( "Fuse - Load Binary Data" );
  
  info.filename = ui_get_open_filename( info.dialog_title );
  if( !info.filename ) { fuse_emulation_unpause(); return; }

  error = utils_read_file( info.filename, &info.file );
  if( error ) { free( info.filename ); fuse_emulation_unpause(); return; }

  info.on_change_filename = &change_load_filename;
  info.on_execute = &load_data;

  /* Information display */
  DialogBoxParam( fuse_hInstance, MAKEINTRESOURCE( IDD_BINARY ), fuse_hWnd,
                  binarydata_proc, ( LPARAM ) &info );

  free( info.filename );
  utils_close_file( &info.file );

  fuse_emulation_unpause();
}
Пример #4
0
static void
change_load_filename( HWND hwndDlg, LONG user_data )
{
  struct binary_info *info = ( struct binary_info * ) user_data;
  
  TCHAR *new_filename;
  utils_file new_file;

  TCHAR buffer[80];
  int error;

  new_filename = ui_get_open_filename( "Fuse - Load Binary Data" );
  if( !new_filename ) return;

  error = utils_read_file( new_filename, &new_file );
  if( error ) { free( new_filename ); return; }

  /* Remove the data for the old file */
  error = utils_close_file( &info->file );
  if( error ) { free( new_filename ); return; }

  free( info->filename );

  /* Put the new data in */
  info->filename = new_filename; info->file = new_file;

  /* And update the displayed information */
  SendDlgItemMessage( hwndDlg, IDC_BINARY_STATIC_PATH, WM_SETTEXT,
                      0, ( LPARAM ) new_filename );

  _sntprintf( buffer, 80, "%lu", (unsigned long) info->file.length );
  SendDlgItemMessage( hwndDlg, IDC_BINARY_EDIT_LENGTH, WM_SETTEXT,
                      0, ( LPARAM ) buffer );
}
Пример #5
0
int snapshot_read( const char *filename )
{
  utils_file file;
  libspectrum_snap *snap = libspectrum_snap_alloc();
  int error;

  error = utils_read_file( filename, &file );
  if( error ) { libspectrum_snap_free( snap ); return error; }

  error = libspectrum_snap_read( snap, file.buffer, file.length,
				 LIBSPECTRUM_ID_UNKNOWN, filename );
  if( error ) {
    utils_close_file( &file ); libspectrum_snap_free( snap );
    return error;
  }

  utils_close_file( &file );

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

  error = libspectrum_snap_free( snap ); if( error ) return error;

  return 0;
}
Пример #6
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;
}
Пример #7
0
raop_t *
raop_init_from_keyfile(int max_clients, raop_callbacks_t *callbacks, const char *keyfile, int *error)
{
    raop_t *raop;
    char *pemstr;

    if (utils_read_file(&pemstr, keyfile) < 0) {
        return NULL;
    }
    raop = raop_init(max_clients, callbacks, pemstr, error);
    free(pemstr);
    return raop;
}
Пример #8
0
int tape_open( const char *filename, int autoload )
{
  utils_file file;
  int error;

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

  error = tape_read_buffer( file.buffer, file.length, LIBSPECTRUM_ID_UNKNOWN,
			    filename, autoload );
  if( error ) { utils_close_file( &file ); return error; }

  utils_close_file( &file );

  return 0;
}
Пример #9
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;
}
Пример #10
0
int rzx_start_playback( const char *filename, int check_snapshot )
{
  utils_file file;
  libspectrum_error libspec_error; int error;
  libspectrum_snap* snap;

  if( rzx_recording ) return 1;

  rzx = libspectrum_rzx_alloc();

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

  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 );

  snap = rzx_get_initial_snapshot();
  if( !snap && check_snapshot ) {
    /* We need to load an external snapshot. Could be skipped if the snapshot
       is preloaded from command line */
    error = utils_open_snap();
    if( error ) return error;
  }

  error = start_playback( rzx );
  if( error ) {
    libspectrum_rzx_free( rzx );
    return error;
  }

  return 0;
}
Пример #11
0
/* Open `filename' and do something sensible with it; autoload tapes
   if `autoload' is true and return the type of file found in `type' */
int
utils_open_file( const char *filename, int autoload,
		 libspectrum_id_t *type_ptr)
{
  utils_file file;
  libspectrum_id_t type;
  libspectrum_class_t class;
  int error;

  error = 0;
  if( rzx_recording ) error = rzx_stop_recording();
  if( rzx_playback  ) error = rzx_stop_playback( 1 );
  if( error ) return error;

  /* Read the file into a buffer */
  if( utils_read_file( filename, &file ) ) return 1;

  /* See if we can work out what it is */
  if( libspectrum_identify_file_with_class( &type, &class, filename,
					    file.buffer, file.length ) ) {
    utils_close_file( &file );
    return 1;
  }

  switch( class ) {
    
  case LIBSPECTRUM_CLASS_UNKNOWN:
    ui_error( UI_ERROR_ERROR, "utils_open_file: couldn't identify `%s'",
	      filename );
    utils_close_file( &file );
    return 1;

  case LIBSPECTRUM_CLASS_RECORDING:
    error = rzx_start_playback_from_buffer( file.buffer, file.length );
    break;

  case LIBSPECTRUM_CLASS_SNAPSHOT:
    error = snapshot_read_buffer( file.buffer, file.length, type );
    pokemem_find_pokfile( filename );
    break;

  case LIBSPECTRUM_CLASS_TAPE:
    error = tape_read_buffer( file.buffer, file.length, type, filename,
			      autoload );
    pokemem_find_pokfile( filename );
    break;

  case LIBSPECTRUM_CLASS_DISK_PLUS3:
    if( !( machine_current->capabilities &
	   LIBSPECTRUM_MACHINE_CAPABILITY_PLUS3_DISK ) ) {
      error = machine_select( LIBSPECTRUM_MACHINE_PLUS3 ); if( error ) break;
    }

    error = specplus3_disk_insert( SPECPLUS3_DRIVE_A, filename, autoload );
    break;

  case LIBSPECTRUM_CLASS_DISK_DIDAKTIK:

    error = didaktik80_disk_insert( DIDAKTIK80_DRIVE_A, filename, autoload );
    break;

  case LIBSPECTRUM_CLASS_DISK_PLUSD:

    if( periph_is_active( PERIPH_TYPE_DISCIPLE ) )
      error = disciple_disk_insert( DISCIPLE_DRIVE_1, filename, autoload );
    else
      error = plusd_disk_insert( PLUSD_DRIVE_1, filename, autoload );
    break;

  case LIBSPECTRUM_CLASS_DISK_OPUS:

    error = opus_disk_insert( OPUS_DRIVE_1, filename, autoload );
    break;

  case LIBSPECTRUM_CLASS_DISK_TRDOS:

    if( !( machine_current->capabilities &
	   LIBSPECTRUM_MACHINE_CAPABILITY_TRDOS_DISK ) &&
        !periph_is_active( PERIPH_TYPE_BETA128 ) ) {
      error = machine_select( LIBSPECTRUM_MACHINE_PENT ); if( error ) break;
    }

    /* Check that we actually got a Beta capable machine to insert the disk */
    if( ( machine_current->capabilities & 
          LIBSPECTRUM_MACHINE_CAPABILITY_TRDOS_DISK ) ||
        periph_is_active( PERIPH_TYPE_BETA128 ) ) {
      error = beta_disk_insert( BETA_DRIVE_A, filename, autoload );
    }
    break;

  case LIBSPECTRUM_CLASS_DISK_GENERIC:
    if( machine_current->machine == LIBSPECTRUM_MACHINE_PLUS3 ||
        machine_current->machine == LIBSPECTRUM_MACHINE_PLUS2A )
      error = specplus3_disk_insert( SPECPLUS3_DRIVE_A, filename, autoload );
    else if( machine_current->machine == LIBSPECTRUM_MACHINE_PENT ||
          machine_current->machine == LIBSPECTRUM_MACHINE_PENT512 ||
          machine_current->machine == LIBSPECTRUM_MACHINE_PENT1024 ||
          machine_current->machine == LIBSPECTRUM_MACHINE_SCORP )
      error = beta_disk_insert( BETA_DRIVE_A, filename, autoload );
    else
      if( periph_is_active( PERIPH_TYPE_BETA128 ) )
        error = beta_disk_insert( BETA_DRIVE_A, filename, autoload );
      else if( periph_is_active( PERIPH_TYPE_DISCIPLE ) )
        error = disciple_disk_insert( DISCIPLE_DRIVE_1, filename, autoload );
      else if( periph_is_active( PERIPH_TYPE_PLUSD ) )
        error = plusd_disk_insert( PLUSD_DRIVE_1, filename, autoload );
    break;

  case LIBSPECTRUM_CLASS_CARTRIDGE_IF2:
    error = if2_insert( filename );
    break;

  case LIBSPECTRUM_CLASS_MICRODRIVE:
    error = if1_mdr_insert( -1, filename );
    break;

  case LIBSPECTRUM_CLASS_CARTRIDGE_TIMEX:
    if( !( machine_current->capabilities &
	   LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) ) {
      error = machine_select( LIBSPECTRUM_MACHINE_TC2068 ); if( error ) break;
    }
    /* Check that we actually got a Dock capable machine to insert the cart */
    if( machine_current->capabilities &
	   LIBSPECTRUM_MACHINE_CAPABILITY_TIMEX_DOCK ) {
      error = dck_insert( filename );
    }
    break;

  case LIBSPECTRUM_CLASS_HARDDISK:
    if( !settings_current.simpleide_active &&
	!settings_current.zxatasp_active   &&
	!settings_current.divide_enabled   &&
	!settings_current.zxcf_active         ) {
      settings_current.zxcf_active = 1;
      periph_update();
    }

    if( settings_current.zxcf_active ) {
      error = zxcf_insert( filename );
    } else if( settings_current.zxatasp_active ) {
      error = zxatasp_insert( filename, LIBSPECTRUM_IDE_MASTER );
    } else if( settings_current.simpleide_active ) {
      error = simpleide_insert( filename, LIBSPECTRUM_IDE_MASTER );
    } else {
      error = divide_insert( filename, LIBSPECTRUM_IDE_MASTER );
    }
    if( error ) return error;
    
    break;

  case LIBSPECTRUM_CLASS_AUXILIARY:
    if( type == LIBSPECTRUM_ID_AUX_POK ) {
      ui_pokemem_selector( filename );
    }
    break;

  default:
    ui_error( UI_ERROR_ERROR, "utils_open_file: unknown class %d", type );
    error = 1;
    break;
  }

  if( error ) { utils_close_file( &file ); return error; }

  utils_close_file( &file );

  if( type_ptr ) *type_ptr = type;

  return 0;
}
Пример #12
0
int
screenshot_scr_read( const char *filename )
{
  int error = 0;
  int i;
  utils_file screen;

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

  switch( screen.length ) {
  case STANDARD_SCR_SIZE:
    memcpy( &RAM[ memory_current_screen ][display_get_addr(0,0)],
	    screen.buffer, screen.length );

    /* If it is a Timex and it is in hi colour or hires mode, switch out of
       hires or hicolour mode */
    if( scld_last_dec.name.b1 || scld_last_dec.name.hires )
      scld_dec_write( 0xff, scld_last_dec.byte & ~HIRES );
    break;

  case HICOLOUR_SCR_SIZE:
    /* If it is a Timex and it is not in hi colour mode, copy screen and switch
        mode if neccesary */
    /* If it is not a Timex copy the mono bitmap and raise an error */
    if( machine_current->timex ) {
      if( !scld_last_dec.name.b1 )
        scld_dec_write( 0xff, ( scld_last_dec.byte & ~HIRESATTR ) | EXTCOLOUR );
      memcpy( &RAM[ memory_current_screen ][display_get_addr(0,0) +
              ALTDFILE_OFFSET], screen.buffer + MONO_BITMAP_SIZE,
	      MONO_BITMAP_SIZE );
    } else
      ui_error( UI_ERROR_INFO,
            "The file contained a TC2048 high-colour screen, loaded as mono");

    memcpy( &RAM[ memory_current_screen ][display_get_addr(0,0)],
              screen.buffer, MONO_BITMAP_SIZE );
    break;

  case HIRES_SCR_SIZE:
    /* If it is a Timex and it is not in hi res mode, copy screen and switch
        mode if neccesary */
    /* If it is not a Timex scale the bitmap and raise an error */
    if( machine_current->timex ) {
      memcpy( &RAM[ memory_current_screen ][display_get_addr(0,0)],
                screen.buffer, MONO_BITMAP_SIZE );

      memcpy( &RAM[ memory_current_screen ][display_get_addr(0,0)] +
              ALTDFILE_OFFSET, screen.buffer + MONO_BITMAP_SIZE,
	      MONO_BITMAP_SIZE );
      if( !scld_last_dec.name.hires )
        scld_dec_write( 0xff,
            ( scld_last_dec.byte & ~( HIRESCOLMASK | HIRES ) ) |
            ( *(screen.buffer + HIRES_ATTR) & ( HIRESCOLMASK | HIRES ) ) );
    } else {
      libspectrum_byte attr = hires_convert_dec( *(screen.buffer + HIRES_ATTR) );

      for( i = 0; i < MONO_BITMAP_SIZE; i++ )
        RAM[ memory_current_screen ][display_get_addr(0,0) + i] =
          convert_hires_to_lores( *(screen.buffer + MONO_BITMAP_SIZE + i),
                                  *(screen.buffer + i) );

      /* set attributes based on hires attribute byte */
      for( i = 0; i < 768; i++ )
        RAM[ memory_current_screen ][display_get_addr(0,0) +
            MONO_BITMAP_SIZE + i] = attr;

      ui_error( UI_ERROR_INFO,
            "The file contained a TC2048 high-res screen, converted to lores");
    }
    break;

  default:
    ui_error( UI_ERROR_ERROR, "'%s' is not a valid scr file", filename );
    error = 1;
  }

  utils_close_file( &screen );

  display_refresh_all();

  return error;
}
Пример #13
0
int
dck_reset( void )
{
  utils_file file;
  size_t num_block = 0;
  libspectrum_dck *dck;
  int error;

  dck_active = 0;

  if( !settings_current.dck_file ) {
    ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );
    return 0;
  }

  dck = libspectrum_dck_alloc();

  error = utils_read_file( settings_current.dck_file, &file );
  if( error ) { libspectrum_dck_free( dck, 0 ); return error; }

  error = libspectrum_dck_read2( dck, file.buffer, file.length,
                                 settings_current.dck_file );
  if( error ) {
    utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error;
  }

  utils_close_file( &file );

  while( dck->dck[num_block] != NULL ) {
    memory_page *page;
    int i;
    libspectrum_dck_bank dck_bank = dck->dck[num_block]->bank;

    if( dck_bank != LIBSPECTRUM_DCK_BANK_HOME &&
        dck_bank != LIBSPECTRUM_DCK_BANK_DOCK &&
        dck_bank != LIBSPECTRUM_DCK_BANK_EXROM ) {
      ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported",
		dck->dck[num_block]->bank );
      libspectrum_dck_free( dck, 0 );
      return 1;
    }

    for( i = 0; i < 8; i++ ) {

      libspectrum_byte *data;
      int j;

      switch( dck->dck[num_block]->access[i] ) {

      case LIBSPECTRUM_DCK_PAGE_NULL:
        break;

      case LIBSPECTRUM_DCK_PAGE_ROM:
        data = memory_pool_allocate( 0x2000 );
	memcpy( data, dck->dck[num_block]->pages[i], 0x2000 );
        for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) {
          page = dck_get_memory_page( dck_bank, i * MEMORY_PAGES_IN_8K + j);
          page->offset = j * MEMORY_PAGE_SIZE;
          page->writable = 0;
          page->save_to_snapshot = 1;
          page->page = data + page->offset;
        }
        break;

      case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY:
      case LIBSPECTRUM_DCK_PAGE_RAM:
	/* Because the scr and snapshot code depends on the standard
	   memory map being in the RAM[] array, we just copy RAM
	   blocks from the HOME bank into the appropriate page; in
	   other cases, we allocate ourselves a new page to store the
	   contents in */
        if( dck_bank == LIBSPECTRUM_DCK_BANK_HOME && i>1 ) {
          for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) {
            page = dck_get_memory_page( dck_bank, i * MEMORY_PAGES_IN_8K + j);
            if( dck->dck[num_block]->access[i] == LIBSPECTRUM_DCK_PAGE_RAM ) {
              memcpy( page->page,
                dck->dck[num_block]->pages[i] + j * MEMORY_PAGE_SIZE,
                MEMORY_PAGE_SIZE );
            } else {
              memset( page->page, 0, MEMORY_PAGE_SIZE );
            }
          }
        } else {
          data = memory_pool_allocate( 0x2000 );
          if( dck->dck[num_block]->access[i] == LIBSPECTRUM_DCK_PAGE_RAM ) {
            memcpy( data, dck->dck[num_block]->pages[i], 0x2000 );
          } else {
            memset( data, 0, 0x2000 );
          }
          for( j = 0; j < MEMORY_PAGES_IN_8K; j++ ) {
            page = dck_get_memory_page( dck_bank, i * MEMORY_PAGES_IN_8K + j);
            page->offset = j * MEMORY_PAGE_SIZE;
            page->writable = 1;
            page->save_to_snapshot = 1;
            page->page = data + page->offset;
          }
        }
        break;

      }
    }
    num_block++;
  }

  dck_active = 1;

  /* Reset contention for pages */
  scld_set_exrom_dock_contention();

  /* Make the menu item to eject the cartridge active */
  ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 );

  return libspectrum_dck_free( dck, 0 );
}
Пример #14
0
int
dck_reset( void )
{
  utils_file file;
  size_t num_block = 0;
  libspectrum_dck *dck;
  int error;

  dck_active = 0;

  if( !settings_current.dck_file ) {
    ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 0 );
    return 0;
  }

  dck = libspectrum_dck_alloc();

  error = utils_read_file( settings_current.dck_file, &file );
  if( error ) { libspectrum_dck_free( dck, 0 ); return error; }

  error = libspectrum_dck_read2( dck, file.buffer, file.length,
                                 settings_current.dck_file );
  if( error ) {
    utils_close_file( &file ); libspectrum_dck_free( dck, 0 ); return error;
  }

  if( utils_close_file( &file ) ) {
    libspectrum_dck_free( dck, 0 );
    return 1;
  }

  while( dck->dck[num_block] != NULL ) {
    memory_page **mem;
    int i;

    switch( dck->dck[num_block]->bank ) {
    case LIBSPECTRUM_DCK_BANK_HOME:
      mem = memory_map_home;
      break;
    case LIBSPECTRUM_DCK_BANK_DOCK:
      mem = memory_map_dock;
      break;
    case LIBSPECTRUM_DCK_BANK_EXROM:
      mem = memory_map_exrom;
      break;
    default:
      ui_error( UI_ERROR_INFO, "Sorry, bank ID %i is unsupported",
		dck->dck[num_block]->bank );
      libspectrum_dck_free( dck, 0 );
      return 1;
    }

    for( i = 0; i < 8; i++ ) {

      switch( dck->dck[num_block]->access[i] ) {

      case LIBSPECTRUM_DCK_PAGE_NULL:
        break;

      case LIBSPECTRUM_DCK_PAGE_ROM:
        mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE );
	if( !mem[i]->page ) return 1;
	memcpy( mem[i]->page, dck->dck[num_block]->pages[i],
		MEMORY_PAGE_SIZE );
        mem[i]->writable = 0;
        mem[i]->source = MEMORY_SOURCE_CARTRIDGE;
        break;

      case LIBSPECTRUM_DCK_PAGE_RAM_EMPTY:
      case LIBSPECTRUM_DCK_PAGE_RAM:
	/* Because the scr and snapshot code depends on the standard
	   memory map being in the RAM[] array, we just copy RAM
	   blocks from the HOME bank into the appropriate page; in
	   other cases, we allocate ourselves a new page to store the
	   contents in */
        if( !(dck->dck[num_block]->bank == LIBSPECTRUM_DCK_BANK_HOME && i>1) ) {
          mem[i]->page = memory_pool_allocate( MEMORY_PAGE_SIZE );
	  if( !mem[i]->page ) return 1;
          mem[i]->writable = 1;
        }
	
        mem[i]->source = MEMORY_SOURCE_CARTRIDGE;
	memcpy( mem[i]->page, dck->dck[num_block]->pages[i],
		MEMORY_PAGE_SIZE );
        break;

      }
    }
    num_block++;
  }

  dck_active = 1;

  /* Make the menu item to eject the cartridge active */
  ui_menu_activate( UI_MENU_ITEM_MEDIA_CARTRIDGE_DOCK_EJECT, 1 );

  return libspectrum_dck_free( dck, 0 );
}