bool oric_dsk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { UINT8 h[256]; UINT8 t[6250+3]; UINT32 stream[100000]; t[6250] = t[6251] = t[6252] = 0; io_generic_read(io, h, 0, 256); int sides = (h[11] << 24) | (h[10] << 16) | (h[ 9] << 8) | h[ 8]; int tracks = (h[15] << 24) | (h[14] << 16) | (h[13] << 8) | h[12]; for(int side=0; side<sides; side++) for(int track=0; track<tracks; track++) { io_generic_read(io, t, 256+6400*(tracks*side + track), 6250); int pos = 0; int sector_size = 128; for(int i=0; i<6250; i++) { if(t[i] == 0xc2 && t[i+1] == 0xc2 && t[i+2] == 0xc2) { raw_w(stream, pos, 16, 0x5224); raw_w(stream, pos, 16, 0x5224); raw_w(stream, pos, 16, 0x5224); i += 2; continue; } if(t[i] == 0xa1 && t[i+1] == 0xa1 && t[i+2] == 0xa1) { raw_w(stream, pos, 16, 0x4489); raw_w(stream, pos, 16, 0x4489); raw_w(stream, pos, 16, 0x4489); int copy; if(t[i+3] == 0xfe) { copy = 7; sector_size = 128 << (t[i+7] & 3); logerror("%02x %x - %02x %02x %02x %02x\n", track, side, t[i+4], t[i+5], t[i+6], t[i+7]); } else if(t[i+3] == 0xfb) copy = sector_size+3; else copy = 0; for(int j=0; j<copy; j++) mfm_w(stream, pos, 8, t[i+3+j]); i += 2+copy; continue; } mfm_w(stream, pos, 8, t[i]); } generate_track_from_levels(track, side, stream, 100000, 0, image); } return true; }
bool dmk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { const int header_size = 16; UINT8 header[header_size]; io_generic_read(io, header, 0, header_size); const int tracks = header[1]; const int track_size = ( header[3] << 8 ) | header[2]; const int heads = (header[4] & 0x10) ? 1 : 2; const bool is_sd = (header[4] & 0x40) ? true : false; const int raw_track_size = 2 * 8 * ( track_size - 0x80 ); if (is_sd) { if (heads == 2) { image->set_variant(floppy_image::DSSD); } else { image->set_variant(floppy_image::SSSD); } } else { if (heads == 2) { image->set_variant(floppy_image::DSDD); } else { image->set_variant(floppy_image::SSDD); } } for (int track = 0; track < tracks; track++) { for (int head = 0; head < heads; head++) { dynamic_array<UINT8> track_data(track_size); dynamic_array<UINT32> raw_track_data(raw_track_size); int iam_location = -1; int idam_location[64]; int dam_location[64]; int tpos = 0; // Read track io_generic_read(io, track_data, header_size + ( heads * track + head ) * track_size, track_size); for (int i = 0; i < 64; i++) { idam_location[i] = -1; dam_location[i] = -1; } // Find IDAM locations UINT16 track_header_offset = 0; UINT16 track_offset = ( ( track_data[track_header_offset + 1] << 8 ) | track_data[track_header_offset] ) & 0x3fff; track_header_offset += 2; while ( track_offset != 0 && track_offset >= 0x83 && track_offset < track_size && track_header_offset < 0x80 ) { // Assume 3 bytes before IDAM pointers are the start of IDAM indicators idam_location[(track_header_offset/2) - 1] = track_offset - 3; // Scan for DAM location for (int i = track_offset + 53; i > track_offset + 10; i--) { if ((track_data[i] == 0xfb || track_data[i] == 0xf8) && track_data[i-1] == 0xa1 && track_data[i-2] == 0xa1) { dam_location[(track_header_offset/2) - 1] = i - 3; break; } } track_offset = ( ( track_data[track_header_offset + 1] << 8 ) | track_data[track_header_offset] ) & 0x3fff; track_header_offset += 2; }; // Find IAM location for(int i = idam_location[0] - 1; i >= 3; i--) { // It's usually 3 bytes but several dumped tracks seem to contain only 2 bytes if (track_data[i] == 0xfc && track_data[i-1] == 0xc2 && track_data[i-2] == 0xc2) { iam_location = i - 3; break; } } int idam_index = 0; int dam_index = 0; for (int offset = 0x80; offset < track_size; offset++) { if (offset == iam_location) { // Write IAM raw_w(raw_track_data, tpos, 16, 0x5224); raw_w(raw_track_data, tpos, 16, 0x5224); raw_w(raw_track_data, tpos, 16, 0x5224); offset += 3; } if (offset == idam_location[idam_index]) { raw_w(raw_track_data, tpos, 16, 0x4489); raw_w(raw_track_data, tpos, 16, 0x4489); raw_w(raw_track_data, tpos, 16, 0x4489); idam_index += 1; offset += 3; } if (offset == dam_location[dam_index]) { raw_w(raw_track_data, tpos, 16, 0x4489); raw_w(raw_track_data, tpos, 16, 0x4489); raw_w(raw_track_data, tpos, 16, 0x4489); dam_index += 1; offset += 3; } mfm_w(raw_track_data, tpos, 8, track_data[offset]); } generate_track_from_levels(track, head, raw_track_data, raw_track_size, 0, image); } } return true; }
bool d88_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) { UINT8 h[32]; io_generic_read(io, h, 0, 32); int cell_count = 0; int track_count = 0; int head_count = 0; switch(h[0x1b]) { case 0x00: cell_count = 100000; track_count = 42; head_count = 2; image->set_variant(floppy_image::DSDD); break; case 0x10: cell_count = 100000; track_count = 82; head_count = 2; image->set_variant(floppy_image::DSQD); break; case 0x20: cell_count = form_factor == floppy_image::FF_35 ? 200000 : 166666; track_count = 82; head_count = 2; image->set_variant(floppy_image::DSHD); break; case 0x30: cell_count = 100000; track_count = 42; head_count = 1; image->set_variant(floppy_image::SSDD); break; case 0x40: cell_count = 100000; track_count = 82; head_count = 1; image->set_variant(floppy_image::SSQD); break; } if(!head_count) return false; UINT32 track_pos[164]; io_generic_read(io, track_pos, 32, 164*4); for(int track=0; track < track_count; track++) for(int head=0; head < head_count; head++) { int pos = LITTLE_ENDIANIZE_INT32(track_pos[track * head_count + head]); if(!pos) continue; UINT32 track_data[210000]; UINT8 sect_data[65536]; int tpos = 0; // gap 4a , IAM and gap 1 for(int i=0; i<80; i++) mfm_w(track_data, tpos, 8, 0x4e); for(int i=0; i<12; i++) mfm_w(track_data, tpos, 8, 0x00); for(int i=0; i< 3; i++) raw_w(track_data, tpos, 16, 0x5224); mfm_w(track_data, tpos, 8, 0xfc); for(int i=0; i<50; i++) mfm_w(track_data, tpos, 8, 0x4e); // Updated after reading the first header int sector_count = 1; int gap3 = 84; for(int i=0; i<sector_count; i++) { UINT8 hs[16]; io_generic_read(io, hs, pos, 16); UINT16 size = LITTLE_ENDIANIZE_INT16(*(UINT16 *)(hs+14)); io_generic_read(io, sect_data, pos+16, size); pos += 16+size; if(i == 0) { sector_count = LITTLE_ENDIANIZE_INT16(*(UINT16 *)(hs+4)); if(size < 512) gap3 = form_factor == floppy_image::FF_35 ? 54 : 50; else gap3 = form_factor == floppy_image::FF_35 ? 84 : 80; } int cpos; UINT16 crc; // sync and IDAM and gap 2 for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00); cpos = tpos; for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489); mfm_w(track_data, tpos, 8, 0xfe); mfm_w(track_data, tpos, 8, hs[0]); mfm_w(track_data, tpos, 8, hs[1]); mfm_w(track_data, tpos, 8, hs[2]); mfm_w(track_data, tpos, 8, hs[3]); crc = calc_crc_ccitt(track_data, cpos, tpos); mfm_w(track_data, tpos, 16, crc); for(int j=0; j<22; j++) mfm_w(track_data, tpos, 8, 0x4e); // sync, DAM, data and gap 3 for(int j=0; j<12; j++) mfm_w(track_data, tpos, 8, 0x00); cpos = tpos; for(int j=0; j< 3; j++) raw_w(track_data, tpos, 16, 0x4489); mfm_w(track_data, tpos, 8, 0xfb); for(int j=0; j<size; j++) mfm_w(track_data, tpos, 8, sect_data[j]); crc = calc_crc_ccitt(track_data, cpos, tpos); mfm_w(track_data, tpos, 16, crc); for(int j=0; j<gap3; j++) mfm_w(track_data, tpos, 8, 0x4e); } // Gap 4b if(tpos > cell_count) throw emu_fatalerror("d88_format: Incorrect layout on track %d head %d, expected_size=%d, current_size=%d", track, head, cell_count, tpos); while(tpos < cell_count-15) mfm_w(track_data, tpos, 8, 0x4e); raw_w(track_data, tpos, cell_count-tpos, 0x9254 >> (16+tpos-cell_count)); generate_track_from_levels(track, head, track_data, cell_count, 0, image); } return true; }