static floperr_t internal_imd_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, void *buffer, size_t buflen) { UINT64 offset; floperr_t err; UINT8 header[1]; // take sector offset err = get_offset(floppy, head, track, sector, sector_is_index, &offset); if (err) return err; floppy_image_read(floppy, header, offset, 1); switch(header[0]) { case 0: break; case 1: case 3: case 5: case 7: floppy_image_read(floppy, buffer, offset+1, buflen); break; default: // all data same floppy_image_read(floppy, header, offset+1, 1); memset(buffer,header[0],buflen); break; } return FLOPPY_ERROR_SUCCESS; }
static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, UINT64 *offset) { UINT64 pos = 0; UINT8 data; INT16 len; int s; if ((head < 0) || (head >= get_tag(floppy)->heads) || (track < 0) || (track >= get_tag(floppy)->tracks) || (sector < 0) ) return FLOPPY_ERROR_SEEKERROR; pos = cqm_get_track_offset(floppy,head,track); s = 0; do { floppy_image_read(floppy, &len, pos, 2); pos+=2; if(len<0) { floppy_image_read(floppy, &data, pos, 1); memset(get_tag(floppy)->buf + s,data, -len); pos++; s += -len; } else { floppy_image_read(floppy, get_tag(floppy)->buf + s, pos, len); pos+=len; s += len; } } while(s<get_tag(floppy)->sector_size*get_tag(floppy)->sector_per_track); if (offset) *offset = sector * get_tag(floppy)->sector_size; return FLOPPY_ERROR_SUCCESS; }
static int d88_get_sector_id(floppy_image_legacy *floppy, int head, int track, int sector_index) { struct d88_tag* tag = get_d88_tag(floppy); uint32_t offset; uint8_t sector_hdr[16]; int x; offset = tag->trackoffset[(track*tag->heads)+head]; if(offset == 0) return 0; floppy_image_read(floppy,sector_hdr,offset,16); // get to sector indexed x=0; while(x<sector_index) { offset += ((sector_hdr[15] << 8) | sector_hdr[14]); offset += 16; floppy_image_read(floppy,sector_hdr,offset,16); x++; } return sector_hdr[2]; }
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 uint32_t d88_get_sector_offset(floppy_image_legacy* floppy, int head, int track, int sector) { struct d88_tag* tag = get_d88_tag(floppy); uint32_t offset = 0; uint8_t sector_hdr[16]; uint32_t len; uint32_t secs; int count; // get offset of the beginning of the track offset = tag->trackoffset[(track*tag->heads)+head]; floppy_image_read(floppy,sector_hdr,offset,16); secs = sector_hdr[4]; for(count=0;count<secs;count++) { floppy_image_read(floppy,sector_hdr,offset,16); if(sector == sector_hdr[2]) { LOG_FORMATS("d88_get_sector_offset - track %i, side %i, sector %02x, returns %08x\n",track,head,sector,offset+16); return offset + 16; } len = (sector_hdr[15] << 8) | sector_hdr[14]; len += 16; offset += len; } LOG_FORMATS("d88_get_sector_offset - track %i, side %i, sector %02x, not found\n",track,head,sector); return 0; }
static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, UINT64 *offset) { UINT64 offs = 0; UINT8 header[5]; UINT8 sector_num; int i; if ((head < 0) || (head >= get_tag(floppy)->heads) || (track < 0) || (track >= get_tag(floppy)->tracks) || (sector < 0) ) return FLOPPY_ERROR_SEEKERROR; offs = imd_get_track_offset(floppy,head,track); floppy_image_read(floppy, header, offs, 5); sector_num = header[3]; offs += 5 + sector_num; // skip header and sector numbering map if(header[2] & 0x80) offs += sector_num; // skip cylinder numbering map if(header[2] & 0x40) offs += sector_num; // skip head numbering map get_tag(floppy)->sector_size = 1 << (header[4] + 7); for(i=0;i<sector;i++) { floppy_image_read(floppy, header, offs, 1); // take sector data type switch(header[0]) { case 0: offs++; break; case 1: case 3: case 5: case 7: offs += get_tag(floppy)->sector_size + 1; break; default: offs += 2; } } if (offset) *offset = offs; return FLOPPY_ERROR_SUCCESS; }
static floperr_t d88_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, uint32_t *sector_length) { struct d88_tag* tag = get_d88_tag(floppy); uint32_t offset; uint8_t sector_hdr[16]; uint32_t len; int count,secs; offset = tag->trackoffset[(track*tag->heads)+head]; floppy_image_read(floppy,sector_hdr,offset,16); secs = sector_hdr[4]; for(count=0;count<secs;count++) { floppy_image_read(floppy,sector_hdr,offset,16); if(sector == sector_hdr[2]) { if(sector_length) *sector_length = (sector_hdr[15] << 8) | sector_hdr[14]; return FLOPPY_ERROR_SUCCESS; } len = (sector_hdr[15] << 8) | sector_hdr[14]; len += 16; offset += len; } return FLOPPY_ERROR_SEEKERROR; }
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 FLOPPY_IDENTIFY( nes_dsk_identify ) { UINT64 size; UINT8 header[3]; *vote = 0; /* get first 3 bytes */ floppy_image_read(floppy, &header, 0, sizeof(header)); /* first check the size of the image */ size = floppy_image_size(floppy); if ((size == 65516) || (size == 131016) || (size == 262016)) { /* the image has an header, hence check the first sector for the magic string */ if (!memcmp(header, "FDS", 3)) *vote = 100; } if ((size == 65500) || (size == 131000) || (size == 262000)) { /* the image has no header, hence let's trust the extension and load the file */ *vote = 100; } return FLOPPY_ERROR_SUCCESS; }
static FLOPPY_CONSTRUCT(oric_dsk_construct) { struct FloppyCallbacks *callbacks; struct oricdsk_tag *tag; UINT8 header[mfm_disk_header_size]; floppy_image_read(floppy, header, 0, mfm_disk_header_size); tag = (struct oricdsk_tag *) floppy_create_tag(floppy, sizeof(struct oricdsk_tag)); if (!tag) return FLOPPY_ERROR_OUTOFMEMORY; tag->heads = pick_integer_le(header, 8, 4); tag->tracks = pick_integer_le(header, 12, 4); tag->geometry = pick_integer_le(header, 16, 4); tag->tracksize = TRACK_SIZE_MFM; memset(tag->sector_data,0,sizeof(tag->sector_data)); callbacks = floppy_callbacks(floppy); callbacks->read_sector = oric_read_sector; callbacks->write_sector = oric_write_sector; callbacks->read_indexed_sector = oric_read_indexed_sector; callbacks->write_indexed_sector = oric_write_indexed_sector; callbacks->get_sector_length = oric_get_sector_length; callbacks->get_heads_per_disk = oric_get_heads_per_disk; callbacks->get_tracks_per_disk = oric_get_tracks_per_disk; callbacks->get_indexed_sector_info = oric_get_indexed_sector_info; return FLOPPY_ERROR_SUCCESS; }
static floperr_t pc_dsk_compute_geometry(floppy_image_legacy *floppy, struct basicdsk_geometry *geometry) { int i; UINT64 size; memset(geometry, 0, sizeof(*geometry)); size = floppy_image_size(floppy); for (i = 0; i < ARRAY_LENGTH(disk_sizes); i++) { if (disk_sizes[i].image_size == size) { geometry->sectors = disk_sizes[i].sectors; geometry->heads = disk_sizes[i].heads; geometry->sector_length = 512; geometry->first_sector_id = 1; geometry->tracks = (int) (size / disk_sizes[i].sectors / disk_sizes[i].heads / geometry->sector_length); return FLOPPY_ERROR_SUCCESS; } } if (size >= 0x1a) { /* * get info from boot sector. * not correct on all disks */ UINT8 scl, spt, heads; floppy_image_read(floppy, &scl, 0x0c, 1); floppy_image_read(floppy, &spt, 0x18, 1); floppy_image_read(floppy, &heads, 0x1A, 1); if (size == ((UINT64) scl) * spt * heads * 0x200) { geometry->sectors = spt; geometry->heads = heads; geometry->sector_length = 512; geometry->first_sector_id = 1; geometry->tracks = scl; return FLOPPY_ERROR_SUCCESS; } } return FLOPPY_ERROR_SUCCESS; }
int td0dsk_t::data_read(UINT8 *buf, UINT16 size) { if (floppy_file_offset + size > floppy_image_size(floppy_file) ) { size = floppy_image_size(floppy_file) - floppy_file_offset; } floppy_image_read(floppy_file,buf,floppy_file_offset,size); floppy_file_offset += size; return size; }
static floperr_t d88_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, uint32_t *sector_length, unsigned long *flags) { struct d88_tag* tag = get_d88_tag(floppy); uint32_t offset; uint8_t sector_hdr[16]; int x; offset = tag->trackoffset[(track*tag->heads)+head]; if(offset == 0) return FLOPPY_ERROR_SEEKERROR; floppy_image_read(floppy,sector_hdr,offset,16); if(sector_index >= sector_hdr[4]) return FLOPPY_ERROR_SEEKERROR; // get to sector indexed x=0; while(x<sector_index) { offset += ((sector_hdr[15] << 8) | sector_hdr[14]); offset += 16; floppy_image_read(floppy,sector_hdr,offset,16); x++; } if(offset > tag->image_size || offset == 0) return FLOPPY_ERROR_SEEKERROR; if(sector_length) *sector_length = (sector_hdr[15] << 8) | sector_hdr[14]; if(cylinder) *cylinder = sector_hdr[0]; if(side) *side = sector_hdr[1]; if(sector) *sector = sector_hdr[2]; if(flags) *flags = 0; return FLOPPY_ERROR_SUCCESS; }
static floperr_t internal_oric_read_sector(floppy_image *floppy, int head, int track, int sector, int sector_is_index, void *buffer, size_t buflen) { UINT64 offset; floperr_t err; err = get_offset(floppy, head, track, sector, sector_is_index, &offset); if (err) return err; floppy_image_read(floppy, buffer, offset, buflen); return FLOPPY_ERROR_SUCCESS; }
static void d88_get_header(floppy_image_legacy* floppy,uint32_t* size, uint8_t* prot, uint8_t* type, uint32_t* offsets) { uint8_t header[D88_HEADER_LEN]; int x,s; floppy_image_read(floppy,header,0,D88_HEADER_LEN); #ifdef SPOT_DUPLICATES // there exist many .d88 files with same data and different headers and // this allows to spot duplicates, making easier to debug softlists. uint32_t temp_size = floppy_image_size(floppy); uint8_t tmp_copy[temp_size - D88_HEADER_LEN]; floppy_image_read(floppy,tmp_copy,D88_HEADER_LEN,temp_size - D88_HEADER_LEN); printf("CRC16: %d\n", ccitt_crc16(0xffff, tmp_copy, temp_size - D88_HEADER_LEN)); #endif if(prot) *prot = header[0x1a]; if(type) *type = header[0x1b]; if(size) { s = 0; s |= header[0x1f] << 24; s |= header[0x1e] << 16; s |= header[0x1d] << 8; s |= header[0x1c]; *size = s; } if(offsets) { for(x=0;x<164;x++) { s = 0; s |= header[0x23 + (x*4)] << 24; s |= header[0x22 + (x*4)] << 16; s |= header[0x21 + (x*4)] << 8; s |= header[0x20 + (x*4)]; *(offsets+x) = s; } } }
static int d88_get_sectors_per_track(floppy_image_legacy *floppy, int head, int track) { struct d88_tag* tag = get_d88_tag(floppy); uint32_t offset; uint8_t sector_hdr[16]; offset = tag->trackoffset[(track*tag->heads)+head]; floppy_image_read(floppy,sector_hdr,offset,16); return sector_hdr[4]; }
static void coupe_sad_interpret_header(floppy_image *floppy, int *heads, int *tracks, int *sectors, int *sector_size) { UINT8 header[SAD_HEADER_LEN]; floppy_image_read(floppy, header, 0, SAD_HEADER_LEN); *heads = header[18]; *tracks = header[19]; *sectors = header[20]; *sector_size = header[21] << 6; }
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 FLOPPY_IDENTIFY(oric_dsk_identify) { UINT8 header[mfm_disk_header_size]; floppy_image_read(floppy, header, 0, mfm_disk_header_size); if ( memcmp( header, MFM_ID, 8 ) ==0) { int heads = pick_integer_le(header, 8, 4); int tracks = pick_integer_le(header, 12, 4); if (floppy_image_size(floppy)==((tracks*heads*TRACK_SIZE_MFM)+mfm_disk_header_size)) { *vote = 100; } else { *vote = 0; } } else { *vote = 0; } return FLOPPY_ERROR_SUCCESS; }
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; }
static floperr_t d88_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen) { uint64_t offset; uint32_t sector_length; offset = d88_get_sector_offset(floppy,head,track,sector); if(d88_get_sector_length(floppy,head,track,sector,§or_length) != FLOPPY_ERROR_SUCCESS) return FLOPPY_ERROR_SEEKERROR; if(offset == 0) return FLOPPY_ERROR_SEEKERROR; if(buflen > sector_length) return FLOPPY_ERROR_INTERNAL; floppy_image_read(floppy,buffer,offset,sector_length); return FLOPPY_ERROR_SUCCESS; }
static FLOPPY_CONSTRUCT(trd_dsk_construct) { struct basicdsk_geometry geometry; UINT8 data[1]; int heads; int cylinders; floppy_image_read( floppy, data, 0x8e3 , 1 ); /* guess geometry of disk */ heads = data[0] & 0x08 ? 1 : 2; cylinders = data[0] & 0x01 ? 40 : 80; memset(&geometry, 0, sizeof(geometry)); geometry.heads = heads; geometry.first_sector_id = 1; geometry.sector_length = 256; geometry.tracks = cylinders; geometry.sectors = 16; return basicdsk_construct(floppy, &geometry); }
static FLOPPY_CONSTRUCT( comx35_dsk_construct ) { UINT8 header[1]; int heads = 1; int cylinders = 35; switch (floppy_image_size(floppy)) { case 35*1*16*128: heads = 1; cylinders = 35; break; case 35*2*16*128: floppy_image_read(floppy, header, 0x12, 1); if (header[0] == 0x01) { heads = 1; cylinders = 70; } else { heads = 2; cylinders = 35; } break; } struct basicdsk_geometry geometry; memset(&geometry, 0, sizeof(geometry)); geometry.heads = heads; geometry.first_sector_id = 0; geometry.sector_length = 128; geometry.tracks = cylinders; geometry.sectors = 16; return basicdsk_construct(floppy, &geometry); }
static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, UINT64 *offset) { UINT64 offs; UINT64 track_offset; UINT8 track_info[0x100]; UINT8 sectors_per_track; int i; /* translate the sector to a raw sector */ /* check to see if we are out of range */ if ((head < 0) || (head >= get_tag(floppy)->heads) || (track < 0) || (track >= get_tag(floppy)->tracks) || (sector < 0) ) return FLOPPY_ERROR_SEEKERROR; track_offset = dsk_get_track_offset(floppy, head, track); floppy_image_read(floppy, track_info, track_offset, 0x100); sectors_per_track = track_info[0x015]; if (!sector_is_index) { if (sector >= sectors_per_track) { return FLOPPY_ERROR_SEEKERROR; } } if (get_tag(floppy)->disk_image_type==0) { get_tag(floppy)->sector_size = (1<<(track_info[0x014]+7)); offs = track_offset + 0x100 +sector * get_tag(floppy)->sector_size; } else { get_tag(floppy)->sector_size = track_info[0x18 + (sector<<3) + 6] + (track_info[0x18+(sector<<3) + 7]<<8); offs = track_offset + 0x100; for (i=0;i<sector;i++) { offs += track_info[0x18 + (i<<3) + 6] + (track_info[0x18+(i<<3) + 7]<<8); } } if (offset) *offset = offs; return FLOPPY_ERROR_SUCCESS; }
static floperr_t dsk_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags) { floperr_t retVal; UINT64 offset; UINT8 sector_info[0x100]; int pos; retVal = get_offset(floppy, head, track, sector_index, FALSE, NULL); offset = dsk_get_track_offset(floppy,head,track); pos = 0x18 + (sector_index << 3); floppy_image_read(floppy, sector_info, offset, 0x100); if (cylinder) *cylinder = sector_info[pos + 0]; if (side) *side = sector_info[pos + 1]; if (sector) *sector = sector_info[pos + 2]; if (sector_length) { *sector_length = 1 << (sector_info[pos + 3] + 7); } if (flags) *flags = (sector_info[pos + 5] & 0x40) ? ID_FLAG_DELETED_DATA : 0; return retVal; }
static floperr_t imd_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags) { UINT64 offset; UINT8 header[5]; UINT8 hd; UINT8 tr; UINT32 sector_size; UINT8 sector_num; offset = imd_get_track_offset(floppy,head,track); floppy_image_read(floppy, header, offset, 5); tr = header[1]; hd = header[2]; sector_num = header[3]; sector_size = 1 << (header[4] + 7); if (sector_index >= sector_num) return FLOPPY_ERROR_SEEKERROR; if (cylinder) { if (head & 0x80) { floppy_image_read(floppy, header, offset + 5 + sector_num+ sector_index, 1); *cylinder = header[0]; } else { *cylinder = tr; } } if (side) { if (head & 0x40) { if (head & 0x80) { floppy_image_read(floppy, header, offset + 5 + 2 * sector_num+sector_index, 1); } else { floppy_image_read(floppy, header, offset + 5 + sector_num+sector_index, 1); } *side = header[0]; } else { *side = hd & 1; } } if (sector) { floppy_image_read(floppy, header, offset + 5 + sector_index, 1); *sector = header[0]; } if (sector_length) { *sector_length = sector_size; } if (flags) { UINT8 skip; if (head & 0x40) { if (head & 0x80) { skip = 3; } else { skip = 2; } } else { skip = 1; } floppy_image_read(floppy, header, offset + 5 + skip * sector_num, 1); *flags = 0; if ((header[0]-1) & 0x02) *flags |= ID_FLAG_DELETED_DATA; if ((header[0]-1) & 0x04) *flags |= ID_FLAG_CRC_ERROR_IN_DATA_FIELD; } return FLOPPY_ERROR_SUCCESS; }
static void mfm_info_cache_sector_info(floppy_image *floppy,int track,int head) { UINT8 track_data[TRACK_SIZE_MFM]; /* initialise these with single density values if single density */ UINT8 IdMark = 0x0fe; UINT8 DataMark = 0x0fb; UINT8 DeletedDataMark = 0x0f8; UINT8 SectorCount; UINT8 SearchCode = 0; UINT8 sector_number = 0; int ptr = 0; int track_offset = oric_get_track_offset(floppy,track,head); floppy_image_read(floppy, track_data, track_offset, TRACK_SIZE_MFM); SectorCount = 0; do { switch (SearchCode) { /* searching for id's */ case 0: { /* found id mark? */ if (track_data[ptr] == IdMark) { sector_number = track_data[ptr+3]-1; /* store pointer to id mark */ get_tag(floppy)->sector_data[sector_number].id_ptr = ptr + track_offset; SectorCount++; /* grab N value - used to skip data in data field */ get_tag(floppy)->sector_data[sector_number].sector_size = (1<< (track_data[ptr+4]+7)); /* skip past id field and crc */ ptr+=7; /* now looking for data field */ SearchCode = 1; } else { /* update position */ ptr++; } } break; /* searching for data id's */ case 1: { /* found data or deleted data? */ if ((track_data[ptr] == DataMark) || (track_data[ptr] == DeletedDataMark)) { /* yes */ get_tag(floppy)->sector_data[sector_number].data_ptr = ptr + track_offset + 1; get_tag(floppy)->sector_data[sector_number].ddam = (track_data[ptr] == DeletedDataMark) ? ID_FLAG_DELETED_DATA : 0; /* skip data field and id */ ptr += get_tag(floppy)->sector_data[sector_number].sector_size + 3; /* now looking for id field */ SearchCode = 0; } else { ptr++; } } break; default: break; } } while (ptr < TRACK_SIZE_MFM); get_tag(floppy)->num_sectors = SectorCount; }
static void read_g64_header(floppy_image_legacy *floppy, struct g64dsk_tag *tag, int head, UINT64 &pos) { UINT8 header[HEADER_LENGTH]; UINT64 start_pos = pos; // read header floppy_image_read(floppy, header, pos, HEADER_LENGTH); // get version tag->version = header[8]; if (!head) LOG_FORMATS("G64 version: %u\n", tag->version); // get number of tracks tag->tracks = header[9]; LOG_FORMATS("G64 side %u tracks: %u\n", head, tag->tracks); // get track size UINT16 track_size = (header[0xb] << 8) | header[0xa]; // get data offsets pos = 0xc; for (int i = 0; i < tag->tracks; i++) { tag->track_offset[head][i] = pick_integer_le(header, pos, 4); if (tag->track_offset[head][i]) { tag->track_offset[head][i] += start_pos; } pos += 4; } // get speed zone information UINT32 track_offs = 0; for (int i = 0; i < tag->tracks; i++) { tag->speed_zone_offset[head][i] = pick_integer_le(header, pos, 4); if (tag->speed_zone_offset[head][i] >= 4) { tag->speed_zone_offset[head][i] += start_pos; } pos += 4; tag->track_size[head][i] = g64_get_track_size(floppy, head, i); if (tag->track_offset[head][i] != 0) { LOG_FORMATS("G64 side %u track %.1f offset %05x length %04x ", head, get_dos_track(i), tag->track_offset[head][i], tag->track_size[head][i]); track_offs = tag->track_offset[head][i]; if (tag->speed_zone_offset[head][i] < 4) { LOG_FORMATS("speed %u\n", tag->speed_zone_offset[head][i]); } else { LOG_FORMATS("speed offset %04x\n", tag->speed_zone_offset[head][i]); } } } pos = track_offs + 2 + track_size; }