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 imgtoolerr_t macbinary_readfile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *destf) { static const UINT32 attrs[] = { IMGTOOLATTR_TIME_CREATED, IMGTOOLATTR_TIME_LASTMODIFIED, IMGTOOLATTR_INT_MAC_TYPE, IMGTOOLATTR_INT_MAC_CREATOR, IMGTOOLATTR_INT_MAC_FINDERFLAGS, IMGTOOLATTR_INT_MAC_COORDX, IMGTOOLATTR_INT_MAC_COORDY, IMGTOOLATTR_INT_MAC_FINDERFOLDER, IMGTOOLATTR_INT_MAC_SCRIPTCODE, IMGTOOLATTR_INT_MAC_EXTENDEDFLAGS, 0 }; imgtoolerr_t err; UINT8 header[128]; const char *basename; int i; UINT32 type_code = 0x3F3F3F3F; UINT32 creator_code = 0x3F3F3F3F; UINT16 finder_flags = 0; UINT16 coord_x = 0; UINT16 coord_y = 0; UINT16 finder_folder = 0; UINT8 script_code = 0; UINT8 extended_flags = 0; imgtool_forkent fork_entries[4]; const imgtool_forkent *data_fork = NULL; const imgtool_forkent *resource_fork = NULL; UINT32 creation_time = 0; UINT32 lastmodified_time = 0; imgtool_attribute attr_values[10]; /* get the forks */ err = imgtool_partition_list_file_forks(partition, filename, fork_entries, sizeof(fork_entries)); if (err) return err; for (i = 0; fork_entries[i].type != FORK_END; i++) { if (fork_entries[i].type == FORK_DATA) data_fork = &fork_entries[i]; else if (fork_entries[i].type == FORK_RESOURCE) resource_fork = &fork_entries[i]; } /* get the attributes */ err = imgtool_partition_get_file_attributes(partition, filename, attrs, attr_values); if (err && (ERRORCODE(err) != IMGTOOLERR_UNIMPLEMENTED)) return err; if (err == IMGTOOLERR_SUCCESS) { creation_time = mac_setup_time(attr_values[0].t); lastmodified_time = mac_setup_time(attr_values[1].t); type_code = attr_values[2].i; creator_code = attr_values[3].i; finder_flags = attr_values[4].i; coord_x = attr_values[5].i; coord_y = attr_values[6].i; finder_folder = attr_values[7].i; script_code = attr_values[8].i; extended_flags = attr_values[9].i; } memset(header, 0, sizeof(header)); /* place filename */ basename = filename; while(basename[strlen(basename) + 1]) basename += strlen(basename) + 1; pascal_from_c_string((unsigned char *) &header[1], 64, basename); place_integer_be(header, 65, 4, type_code); place_integer_be(header, 69, 4, creator_code); place_integer_be(header, 73, 1, (finder_flags >> 8) & 0xFF); place_integer_be(header, 75, 2, coord_x); place_integer_be(header, 77, 2, coord_y); place_integer_be(header, 79, 2, finder_folder); place_integer_be(header, 83, 4, data_fork ? data_fork->size : 0); place_integer_be(header, 87, 4, resource_fork ? resource_fork->size : 0); place_integer_be(header, 91, 4, creation_time); place_integer_be(header, 95, 4, lastmodified_time); place_integer_be(header, 101, 1, (finder_flags >> 0) & 0xFF); place_integer_be(header, 102, 4, 0x6D42494E); place_integer_be(header, 106, 1, script_code); place_integer_be(header, 107, 1, extended_flags); place_integer_be(header, 122, 1, 0x82); place_integer_be(header, 123, 1, 0x81); place_integer_be(header, 124, 2, ccitt_crc16(0, header, 124)); stream_write(destf, header, sizeof(header)); if (data_fork) { err = imgtool_partition_read_file(partition, filename, "", destf, NULL); if (err) return err; stream_fill(destf, 0, pad128(data_fork->size)); } if (resource_fork) { err = imgtool_partition_read_file(partition, filename, "RESOURCE_FORK", destf, NULL); if (err) return err; stream_fill(destf, 0, pad128(resource_fork->size)); } return IMGTOOLERR_SUCCESS; }
void ti99_floppy_format::generate_track_fm(int track, int head, int cell_size, UINT8* trackdata, floppy_image *image) { int track_size_cells = 200000000/cell_size; std::vector<UINT32> buffer; // The TDF has a long track lead-out that makes the track length sum up // to 3253; this is too long for the number of cells in the real track. // This was either an error when that format was defined, // or it is due to the fact that when reading a track via // the controller, after the track has been read, the controller still // delivers some FF values until it times out. // Accordingly, we limit the track size to cell_number / 16, // which means 3125 for FM // This also means that Gap 4 (lead-out) is not 231 bytes long but only 103 bytes int track_size = track_size_cells / 16; short crc1, crc2, found_crc; int start = 16; if (check_for_address_marks(trackdata, floppy_image::FM)==false) { if (head==0 && track==0) osd_printf_warning("ti99_dsk: Cannot find FM address marks on track %d, head %d; likely broken or unformatted.\n", track, head); return; } // Found a track; we now know where the address marks are: // (start is positioned at the pre-id gap) // IDAM: start + 6 + n*334 // DAM: start + 30 + n*334 // and the CRCs are at // CRC1: start + 11 + n*334 // CRC2: start + 287 + n*334 // If the CRCs are F7F7, we recalculate them. for (int i=0; i < track_size; i++) { if (((i-start-6)%334==0) && (i < start + 9*334)) { // IDAM raw_w(buffer, 16, 0xf57e, cell_size); } else { if (((i-start-30)%334==0) && (i < start + 9*334)) { // DAM // FB (1111010101101111) = normal data, F8 (1111010101101010)= deleted data raw_w(buffer, 16, (trackdata[i]==0xf8)? 0xf56a : 0xf56f, cell_size); } else { if (((i-start-11)%334==0) && (i < start + 9*334)) { // CRC1 crc1 = ccitt_crc16(0xffff, &trackdata[i-5], 5); found_crc = (trackdata[i]<<8 | trackdata[i+1]); if ((found_crc & 0xffff) == 0xf7f7) { // PC99 format: no real CRC; replace it // Also, when converting from SDF we let this method create the proper CRC. // osd_printf_verbose("Warning: PC99 format using pseudo CRC1; replace by %04x\n", crc1); trackdata[i] = (crc1 >> 8) & 0xff; trackdata[i+1] = crc1 & 0xff; found_crc = crc1; } if (crc1 != found_crc) { osd_printf_error("ti99_dsk: Warning: CRC1 does not match (track=%d, head=%d). Found = %04x, calc = %04x\n", track, head, found_crc& 0xffff, crc1& 0xffff); } } else { if (((i-start-287)%334==0) && (i < start + 9*334)) { // CRC2 crc2 = ccitt_crc16(0xffff, &trackdata[i-SECTOR_SIZE-1], SECTOR_SIZE+1); found_crc = (trackdata[i]<<8 | trackdata[i+1]); if ((found_crc & 0xffff) == 0xf7f7) { // PC99 format: no real CRC; replace it // osd_printf_verbose("Warning: PC99 format using pseudo CRC2; replace by %04x\n", crc2); trackdata[i] = (crc2 >> 8) & 0xff; trackdata[i+1] = crc2 & 0xff; found_crc = crc2; } if (crc2 != found_crc) { osd_printf_error("ti99_dsk: Warning: CRC2 does not match (track=%d, head=%d). Found = %04x, calc = %04x\n", track, head, found_crc& 0xffff, crc2& 0xffff); } }
static imgtoolerr_t macbinary_writefile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts) { static const UINT32 attrs[] = { IMGTOOLATTR_TIME_CREATED, IMGTOOLATTR_TIME_LASTMODIFIED, IMGTOOLATTR_INT_MAC_TYPE, IMGTOOLATTR_INT_MAC_CREATOR, IMGTOOLATTR_INT_MAC_FINDERFLAGS, IMGTOOLATTR_INT_MAC_COORDX, IMGTOOLATTR_INT_MAC_COORDY, IMGTOOLATTR_INT_MAC_FINDERFOLDER, IMGTOOLATTR_INT_MAC_SCRIPTCODE, IMGTOOLATTR_INT_MAC_EXTENDEDFLAGS, 0 }; imgtoolerr_t err; imgtool_image *image = imgtool_partition_image(partition); UINT8 header[128]; UINT32 datafork_size; UINT32 resourcefork_size; UINT64 total_size; UINT32 creation_time; UINT32 lastmodified_time; //int version; imgtool_attribute attr_values[10]; UINT32 type_code; UINT32 creator_code; UINT16 finder_flags; UINT16 coord_x; UINT16 coord_y; UINT16 finder_folder; UINT8 script_code = 0; UINT8 extended_flags = 0; /* read in the header */ memset(header, 0, sizeof(header)); stream_read(sourcef, header, sizeof(header)); /* check magic and zero fill bytes */ if (header[0] != 0x00) return IMGTOOLERR_CORRUPTFILE; if (header[74] != 0x00) return IMGTOOLERR_CORRUPTFILE; if (header[82] != 0x00) return IMGTOOLERR_CORRUPTFILE; datafork_size = pick_integer_be(header, 83, 4); resourcefork_size = pick_integer_be(header, 87, 4); total_size = stream_size(sourcef); /* size of a MacBinary header is always 128 bytes */ if (total_size - pad128(datafork_size) - pad128(resourcefork_size) != 128) return IMGTOOLERR_CORRUPTFILE; /* check filename length byte */ if ((header[1] <= 0x00) || (header[1] > 0x3F)) return IMGTOOLERR_CORRUPTFILE; /* check the CRC */ if (pick_integer_be(header, 124, 2) != ccitt_crc16(0, header, 124)) { /* the CRC does not match; this file is MacBinary I */ //version = 1; } else if (pick_integer_be(header, 102, 4) != 0x6D42494E) { /* did not see 'mBIN'; this file is MacBinary II */ if (header[122] < 0x81) return IMGTOOLERR_CORRUPTFILE; if (header[123] < 0x81) return IMGTOOLERR_CORRUPTFILE; //version = 2; } else { /* we did see 'mBIN'; this file is MacBinary III */ if (header[122] < 0x82) return IMGTOOLERR_CORRUPTFILE; if (header[123] < 0x81) return IMGTOOLERR_CORRUPTFILE; //version = 3; } type_code = pick_integer_be(header, 65, 4); creator_code = pick_integer_be(header, 69, 4); finder_flags = pick_integer_be(header, 73, 1) << 8; coord_x = pick_integer_be(header, 75, 2); coord_y = pick_integer_be(header, 77, 2); finder_folder = pick_integer_be(header, 79, 2); creation_time = pick_integer_be(header, 91, 4); lastmodified_time = pick_integer_be(header, 95, 4); if (image) { /* write out both forks */ err = write_fork(partition, filename, "", sourcef, sizeof(header), datafork_size, opts); if (err) return err; err = write_fork(partition, filename, "RESOURCE_FORK", sourcef, sizeof(header) + pad128(datafork_size), resourcefork_size, opts); if (err) return err; /* set up attributes */ attr_values[0].t = mac_crack_time(creation_time); attr_values[1].t = mac_crack_time(lastmodified_time); attr_values[2].i = type_code; attr_values[3].i = creator_code; attr_values[4].i = finder_flags; attr_values[5].i = coord_x; attr_values[6].i = coord_y; attr_values[7].i = finder_folder; attr_values[8].i = script_code; attr_values[9].i = extended_flags; err = imgtool_partition_put_file_attributes(partition, filename, attrs, attr_values); if (err) return err; } return IMGTOOLERR_SUCCESS; }