Beispiel #1
0
static floperr_t g64_read_track(floppy_image_legacy *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen)
{
    /*

        The following is written into the buffer:

        n bytes of track data
        1982 bytes of speed zone data

        get_track_size() returns n (size of track data)

    */

    struct g64dsk_tag *tag = get_tag(floppy);
    floperr_t err;
    UINT64 track_offset;
    UINT16 track_length = tag->track_size[head][track];

    // get track offset
    err = get_track_offset(floppy, head, track, &track_offset);

    if (err)
        return err;

    if ((head <= tag->heads) && track_offset)
    {
        if (buflen < track_length) {
            printf("G64 track buffer too small: %u < %u!", (UINT32)buflen, track_length);
            exit(-1);
        }

        // read track data
        floppy_image_read(floppy, ((UINT8*)buffer), track_offset + 2, track_length); // skip the 2 track length bytes in the beginning of track data

        if (tag->speed_zone_offset[head][track] > 3)
        {
            // read speed block
            floppy_image_read(floppy, ((UINT8*)buffer) + track_length, tag->speed_zone_offset[head][track], G64_SPEED_BLOCK_SIZE);
        }
        else
        {
            // create a speed block with the same speed zone for the whole track
            UINT8 speed = tag->speed_zone_offset[head][track] & 0x03;
            UINT8 speed_byte = (speed << 6) | (speed << 4) | (speed << 2) | speed;

            memset(((UINT8*)buffer) + track_length, speed_byte, G64_SPEED_BLOCK_SIZE);
        }

        LOG_FORMATS("G64 side %u track %.1f length %u\n", head, get_dos_track(track), track_length);
    }
    else
    {
        // no data for given track, or tried to read side 1
        memset(((UINT8*)buffer), 0, buflen);

        LOG_FORMATS("G64 side %u track %.1f\n", head, get_dos_track(track));
    }

    return FLOPPY_ERROR_SUCCESS;
}
Beispiel #2
0
static floperr_t g64_read_track(floppy_image *floppy, int head, int track, UINT64 offset, void *buffer, size_t buflen)
{
	struct g64dsk_tag *tag = get_tag(floppy);
	floperr_t err;
	UINT64 track_offset;
	UINT16 track_length = 0;

	/* get track offset */
	err = get_track_offset(floppy, head, track, &track_offset);

	if (err)
		return err;

	if (!head && track_offset)
	{
		if (buflen < tag->track_size) { printf("G64 track buffer too small: %u!", (UINT32)buflen); exit(-1); }

		/* read track */
		floppy_image_read(floppy, buffer, track_offset + 2, tag->track_size);
	}
	else
	{
		/* set track length to 0 */
		memset(buffer, 0, buflen);
	}

	if (LOG) LOG_FORMATS("G64 track %.1f length %u\n", get_dos_track(track), track_length);

	return FLOPPY_ERROR_SUCCESS;
}
Beispiel #3
0
static UINT32 g64_get_track_size(floppy_image *floppy, int head, int track)
{
	/* get track offset */
	UINT64 track_offset;
	floperr_t err = get_track_offset(floppy, head, track, &track_offset);

	if (err)
		return 0;

	/* read track length */
	UINT8 size[2];
	floppy_image_read(floppy, &size, track_offset, 2);
	UINT32 track_length = (size[1] << 8) | size[0];

	return track_length;
}
Beispiel #4
0
static UINT32 g64_get_track_size(floppy_image_legacy *floppy, int head, int track)
{
    // get track offset
    UINT32 track_length = 0;
    UINT64 track_offset;
    floperr_t err = get_track_offset(floppy, head, track, &track_offset);

    if (err)
        return 0;

    // read track length
    if (track_offset > 0)
    {
        UINT8 size[2];
        floppy_image_read(floppy, &size, track_offset, 2);
        track_length = pick_integer_le(size, 0, 2);
    }

    return track_length;
}
Beispiel #5
0
void toc_extract( WINDOW * win )
{
  static const char * ext[] = { "avr", "raw", "raw", "wav" };
  char pathname[ 256 ];
  char prog_info[ 64 ];
  char buf[ 128 ];
  struct avr_header * avrh;
  struct wave_header * wavh;
  struct audio_entry entry;
  struct audio_stream * as;
  struct _toc_data * data;
  struct device_info * info;
  OBJECT * ck;
  int format, i, max, track_no;
  int fd, swap;
  long offset, length, position, end, progress, total_length;
  long max_buf_blocks, nblocks;
  void * buffer;

  if( !fileselect( preferences.toc_dest, "", "TXT_EXTDEST" ) )
    return;
  strrchr( preferences.toc_dest, '\\' )[1] = '\0';

  data = DataSearch( win, TW_MAGIC );
  max = data->n_tracks;
  format = fmt_popup.selected;
  total_length = 0;
  buffer = alloc_comm_buffer( BUFSIZE );
  if( !buffer )
    return;
  for( i = 0; i < max; i++ )
  {
    ck = data->tree + 1 + TF_CK + i * data->n_obj;
    if( ! (ck->ob_state & SELECTED) )
      continue;
    offset = toc_address( data->f[i].beg_time );
    length = toc_address( data->f[i].end_time ) + 1 - offset;
    if( length > 0 )
      total_length += length;
  }
  max_buf_blocks = BUFSIZE / 2352;

  progress = 0;
  progress_init( get_string( "TXT_EXTMSG" ), total_length );
  progress_activate_cancel( 1 );
  progress_init_timer();

  log_begin();
  log_printf( "*** Begin of a track extraction session\n\n" );
  as = NULL;
  for( i = 0; i < max; i++ )
  {
    ck = data->tree + 1 + TF_CK + i * data->n_obj;
    if( ! (ck->ob_state & SELECTED) )
      continue;
    offset = toc_address( data->f[i].beg_time );
    length = toc_address( data->f[i].end_time ) + 1 - offset;
    if( length <= 0 )
      continue;
    track_no = i + 1;
    position = get_track_offset( &data->toc, track_no, &end );
    if( toc_popup.selected == 0 )
      gen_daoimg_entry( &entry, toc_info.toc_file, track_no,
                        offset - position, end - offset - length );
    else
    {
      info = (struct device_info*)toc_popup.item[toc_popup.selected].info;
      gen_cd_entry( &entry, info, track_no, offset - position, end - offset - length );
    }
    if( as )
      as = audio_reopen( as, &entry );
    else
      as = audio_open( &entry );
    if( as == NULL )
      continue;

    sprintf( prog_info, get_string( "TXT_EXTTRK" ), track_no );
    progress_setinfo( prog_info );

    sprintf( pathname, "%strack%02d.%s", preferences.toc_dest, track_no, ext[ format ] );
    fd = open( pathname, O_WRONLY|O_CREAT|O_TRUNC );
    if( fd == -1 )
    {
      audio_close( as );
      alert_msg( "AL_FILERR", 1, pathname );
      goto error;
    }
    switch( format )
    {
    case 0:        /* AVR */
      avrh = (struct avr_header *) buf;
      avrh->avr_id = '2BIT';
      memset( avrh->name, 0, 8 );
      avrh->num_voices = 0xFFFF;
      avrh->num_bits = 16;
      avrh->signe = 0xffff;
      avrh->loop = 0;
      avrh->midi = 0xffff;
      avrh->freq_type.frequence = 0xff00ac44L;
      avrh->length = length * (2352 / 2);
      avrh->beg_loop = 0;
      avrh->end_loop = avrh->length;
      memset( avrh->reserved, 0, 26 + 64 );
      write( fd, avrh, sizeof( *avrh ) );
      swap = as->little_endian;
      break;
    case 1:        /* RAW big-endian */
      swap = as->little_endian;
      break;
    case 2:        /* RAW little-endian */
      swap = !as->little_endian;
      break;
    case 3:        /* WAVE */
      wavh = (struct wave_header *) buf;
      wavh->riff_id = 'RIFF';
      wavh->riff_len = swap_long( length * 2352 + 36 );
      wavh->wave_id = 'WAVE';
      wavh->fmt_id = 'fmt ';
      wavh->fmt_size = 0x10000000L;
      wavh->fmt_compression_code = 0x0100;
      wavh->fmt_channels = 0x0200;
      wavh->fmt_freq = 0x44ac0000L;
      wavh->fmt_bytes_sec = 0x10b10200L;
      wavh->fmt_block_align = 0x0400;
      wavh->fmt_num_bits = 0x1000;
      wavh->data_id = 'data';
      wavh->data_size = swap_long( length * 2352 );
      write( fd, wavh, sizeof( *wavh ) );
      swap = !as->little_endian;
      break;
    }
    while( length > 0 )
    {
      if( yield() )
      {
        audio_close( as );
        alert_msg( "AL_EXTINT", 1 );
        goto error;
      }
      nblocks = MIN( length, max_buf_blocks );
      if( audio_read( as, buffer, nblocks ) == 0 )
      {
        audio_close( as );
        goto error;
      }
      if( swap )
        swap_endian( buffer, nblocks * 2352 );
      if( write( fd, buffer, nblocks * 2352 ) == -1 )
      {
        close( fd );
        audio_close( as );
        alert_msg( "AL_FWRTERR", 1, pathname );
        goto error;
      }
      length -= nblocks;
      progress += nblocks;
      progress_setcount( progress );
    }
    close( fd );
  }
  audio_close( as );
error:
  log_printf( "*** End of the track extraction session\n\n" );
  log_end();
  progress_exit();
  free_comm_buffer( buffer );

}
Beispiel #6
0
int toc_readtoc( WINDOW * win )
{
  struct _toc_data * data;
  struct idao_stream * in;
  const static char * type[] = { "Audio", "Data mode 1", "Data mode 2", "Data" };
  long beg, end;
  int m, s, f;
  int i, entry, mode;

  data = DataSearch( win, TW_MAGIC );
  if( data == NULL )
  {
    data = new_toc_data( );
    if( !data ) return -1;
  }

  busybee();

  if( toc_popup.selected == 0 )
    in = idao_open_file( toc_info.toc_file );
  else
    in = idao_open_cd( toc_popup.item[toc_popup.selected].info );
  if( !in ) goto readerr;

  data->toc = in->toc;

  /* Analyse de la toc */
  entry = get_toc_entry( &data->toc, 0xa1, data->toc.head.last_track );
  data->n_tracks = desc( data->toc, entry ).pmin;

  if( toc_gen_tree( data ) ) goto readerr2;

  for( i=0; i<data->n_tracks; i++ )
  {
    sprintf( data->f[i].tno, "%2d", i + 1 );
    beg = get_track_offset( &data->toc, i + 1, &end );
    msf( beg, &m, &s, &f );
    sprintf( data->f[i].beg_time, "%02d%02d%02d", m, s, f );
    msf( end - 1, &m, &s, &f );
    mode = get_mode( &data->toc, i + 1 );
    if( mode < 0 ) mode = 3;
    objc_enable( data->tree, i*data->n_obj + 1 + TF_CK, mode == 0 /*mode != 3*/ );
    data->tree[ i*data->n_obj + 1 + TF_TYPE ].ob_spec.free_string = type[ mode ];
    sprintf( data->f[i].end_time, "%02d%02d%02d", m, s, f );
    data->tree[ i*data->n_obj + 1 + TF_TNO ].ob_spec.free_string = data->f[i].tno;
  }
  idao_close( in );

  FormAttach( win, data->tree, form_mgr );
  DataAttach( win, TW_MAGIC, data );
  EvntAttach( win, WM_DESTROY, toc_destroy );

  wind_center( win, -1, data->tree->ob_height );
  objc_redraw( data->tree, 0 );

  arrow();
  return 0;
readerr2:
  idao_close( in );
readerr:
  free( data );
  arrow();
  alert_msg( "AL_CANTREAD", 1 );
  return -1;
}