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