bool harddisk_image_device::call_create(int create_format, option_resolution *create_args) { int err; UINT32 sectorsize, hunksize; UINT32 cylinders, heads, sectors, totalsectors; astring metadata; cylinders = option_resolution_lookup_int(create_args, 'C'); heads = option_resolution_lookup_int(create_args, 'H'); sectors = option_resolution_lookup_int(create_args, 'S'); sectorsize = option_resolution_lookup_int(create_args, 'L'); hunksize = option_resolution_lookup_int(create_args, 'K'); totalsectors = cylinders * heads * sectors; /* create the CHD file */ chd_codec_type compression[4] = { CHD_CODEC_NONE }; err = m_origchd.create(*image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, sectorsize, compression); if (err != CHDERR_NONE) goto error; /* if we created the image and hence, have metadata to set, set the metadata */ metadata.format(HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize); err = m_origchd.write_metadata(HARD_DISK_METADATA_TAG, 0, metadata); m_origchd.close(); if (err != CHDERR_NONE) goto error; return internal_load_hd(); error: return IMAGE_INIT_FAIL; }
static DEVICE_CREATE(mess_hd) { int err; char metadata[256]; UINT32 sectorsize, hunksize; UINT32 cylinders, heads, sectors, totalsectors; cylinders = option_resolution_lookup_int(create_args, 'C'); heads = option_resolution_lookup_int(create_args, 'H'); sectors = option_resolution_lookup_int(create_args, 'S'); sectorsize = option_resolution_lookup_int(create_args, 'L'); hunksize = option_resolution_lookup_int(create_args, 'K'); totalsectors = cylinders * heads * sectors; /* create the CHD file */ err = chd_create_ref(image, (UINT64)totalsectors * (UINT64)sectorsize, hunksize, CHDCOMPRESSION_NONE, NULL); if (err != CHDERR_NONE) goto error; sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize); return internal_load_mess_hd(image, metadata); error: return INIT_FAIL; }
static FLOPPY_CONSTRUCT(pc_dsk_construct) { floperr_t err; struct basicdsk_geometry geometry; if (params) { /* create */ memset(&geometry, 0, sizeof(geometry)); geometry.heads = option_resolution_lookup_int(params, PARAM_HEADS); geometry.tracks = option_resolution_lookup_int(params, PARAM_TRACKS); geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS); geometry.first_sector_id = 1; geometry.sector_length = 512; } else { /* open */ err = pc_dsk_compute_geometry(floppy, &geometry); if (err) return err; } return basicdsk_construct(floppy, &geometry); }
bool harddisk_image_device::call_create(int create_format, option_resolution *create_args) { int err; char metadata[256]; UINT32 sectorsize, hunksize; UINT32 cylinders, heads, sectors, totalsectors; cylinders = option_resolution_lookup_int(create_args, 'C'); heads = option_resolution_lookup_int(create_args, 'H'); sectors = option_resolution_lookup_int(create_args, 'S'); sectorsize = option_resolution_lookup_int(create_args, 'L'); hunksize = option_resolution_lookup_int(create_args, 'K'); totalsectors = cylinders * heads * sectors; /* create the CHD file */ err = chd_create_file(image_core_file(), (UINT64)totalsectors * (UINT64)sectorsize, hunksize, CHDCOMPRESSION_NONE, NULL); if (err != CHDERR_NONE) goto error; sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, sectorsize); return internal_load_hd(metadata); error: return IMAGE_INIT_FAIL; }
static imgtoolerr_t mess_hd_image_create(imgtool_image *image, imgtool_stream *f, option_resolution *createoptions) { UINT32 blocksize, cylinders, heads, sectors, seclen; /* read options */ blocksize = option_resolution_lookup_int(createoptions, mess_hd_createopts_blocksize); cylinders = option_resolution_lookup_int(createoptions, mess_hd_createopts_cylinders); heads = option_resolution_lookup_int(createoptions, mess_hd_createopts_heads); sectors = option_resolution_lookup_int(createoptions, mess_hd_createopts_sectors); seclen = option_resolution_lookup_int(createoptions, mess_hd_createopts_seclen); return imghd_create(f, blocksize, cylinders, heads, sectors, seclen); }
static imgtoolerr_t vzsnapshot_writefile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts) { imgtoolerr_t ret; int fnameopt; vzdos_dirent entry; UINT8 header[24]; /* get header infos from file */ stream_read(sourcef, header, sizeof(header)); /* prepare directory entry */ entry.ftype = header[21] == 0xF1 ? 'B' : 'T'; entry.delimitor = ':'; entry.start_address = pick_integer_le(header, 22, 2); /* filename from header or directly? */ fnameopt = option_resolution_lookup_int(opts, 'F'); if (fnameopt == 0) { memcpy(&entry.fname, &header[4], 8); } else { /* TODO: check for leading spaces and strip */ if (strlen(filename) > 8 || strlen(filename) < 1) return IMGTOOLERR_BADFILENAME; memcpy(&entry.fname, filename, strlen(filename) - 3); } /* write file to disk */ ret = vzdos_writefile(partition, 24, sourcef, &entry); if (ret) return ret; return IMGTOOLERR_SUCCESS; }
bool datapack_device::call_create(int format_type, option_resolution *create_args) { static const UINT8 opk_head[6] = {'O', 'P', 'K', 0x00, 0x00, 0x00}; if (create_args != NULL) { m_id = 0x40; m_id |= (option_resolution_lookup_int(create_args, 'R')) ? 0x00 : 0x02; m_id |= (option_resolution_lookup_int(create_args, 'P')) ? 0x04 : 0x00; m_id |= (option_resolution_lookup_int(create_args, 'W')) ? 0x00 : 0x08; m_id |= (option_resolution_lookup_int(create_args, 'B')) ? 0x00 : 0x10; m_id |= (option_resolution_lookup_int(create_args, 'C')) ? 0x20 : 0x00; m_size = option_resolution_lookup_int(create_args, 'S'); } else { // 64k RAM datapack by default m_id = 0x7c; m_size = 0x08; } fwrite(opk_head, 6); fwrite(&m_id, 1); fwrite(&m_size, 1); return IMAGE_INIT_PASS; }
static FLOPPY_CONSTRUCT(vz_construct) { struct basicdsk_geometry geometry; memset(&geometry, 0, sizeof(geometry)); if (params) { geometry.heads = option_resolution_lookup_int(params, PARAM_HEADS); geometry.tracks = option_resolution_lookup_int(params, PARAM_TRACKS); geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS); geometry.first_sector_id = option_resolution_lookup_int(params, PARAM_FIRST_SECTOR_ID); geometry.sector_length = option_resolution_lookup_int(params, PARAM_SECTOR_LENGTH); } else { geometry.heads = 1; geometry.tracks = 40; geometry.sectors = 16; geometry.first_sector_id = 0; geometry.sector_length = floppy_image_size(floppy)/geometry.tracks/geometry.sectors; } return basicdsk_construct(floppy, &geometry); }
static FLOPPY_CONSTRUCT(compis_dsk_construct) { struct basicdsk_geometry geometry; memset(&geometry, 0, sizeof(geometry)); geometry.heads = 1; geometry.first_sector_id = 1; geometry.sector_length = 512; if (params) { /* create */ geometry.tracks = option_resolution_lookup_int(params, PARAM_TRACKS); geometry.sectors = option_resolution_lookup_int(params, PARAM_SECTORS); } else { /* open */ if (!compis_get_tracks_and_sectors(floppy, &geometry.tracks, &geometry.sectors)) return FLOPPY_ERROR_INVALIDIMAGE; } return basicdsk_construct(floppy, &geometry); }
/* create a new file or overwrite a file */ static imgtoolerr_t vzdos_diskimage_writefile(imgtool_partition *partition, const char *filename, const char *fork, imgtool_stream *sourcef, option_resolution *opts) { imgtoolerr_t ret; int ftype; vzdos_dirent entry; /* TODO: check for leading spaces and strip */ if (strlen(filename) > 8 || strlen(filename) < 1) return IMGTOOLERR_BADFILENAME; /* prepare directory entry */ ftype = option_resolution_lookup_int(opts, 'T'); switch (ftype) { case 0: entry.ftype = 'T'; entry.start_address = 31465; break; case 1: entry.ftype = 'B'; entry.start_address = 31465; /* ??? */ break; case 2: entry.ftype = 'D'; entry.start_address = 31465; /* ??? */ break; default: break; } entry.delimitor = ':'; memset(&entry.fname, 0x20, 8); /* pad with spaces */ memcpy(&entry.fname, filename, strlen(filename)); /* write file to disk */ ret = vzdos_writefile(partition, 0, sourcef, &entry); if (ret) return ret; return IMGTOOLERR_SUCCESS; }
static floperr_t trs80_jv1_construct(floppy_image *floppy, option_resolution *params) { struct basicdsk_geometry geometry; memset(&geometry, 0, sizeof(geometry)); geometry.heads = TRS80_JV1_HEADS; geometry.sectors = TRS80_JV1_SECTORS; geometry.first_sector_id = TRS80_JV1_FIRSTSECTORID; geometry.sector_length = TRS80_JV1_SECTORLENGTH; if (params) { /* create */ geometry.tracks = option_resolution_lookup_int(params, PARAM_TRACKS); } else { /* load */ geometry.tracks = (int) (floppy_image_size(floppy) / geometry.heads / geometry.sectors / geometry.sector_length); } return basicdsk_construct(floppy, &geometry); }
static imgtoolerr_t os9_diskimage_create(imgtool_image *img, imgtool_stream *stream, option_resolution *opts) { imgtoolerr_t err; dynamic_buffer header; UINT32 heads, tracks, sectors, sector_bytes, first_sector_id; UINT32 cluster_size, owner_id; UINT32 allocation_bitmap_bits, allocation_bitmap_lsns; UINT32 attributes, format_flags, disk_id; UINT32 i; INT32 total_allocated_sectors; const char *title; time_t t; struct tm *ltime; time(&t); ltime = localtime(&t); heads = option_resolution_lookup_int(opts, 'H'); tracks = option_resolution_lookup_int(opts, 'T'); sectors = option_resolution_lookup_int(opts, 'S'); sector_bytes = option_resolution_lookup_int(opts, 'L'); first_sector_id = option_resolution_lookup_int(opts, 'F'); title = ""; header.resize(sector_bytes); if (sector_bytes > 256) sector_bytes = 256; cluster_size = 1; owner_id = 1; disk_id = 1; attributes = 0; allocation_bitmap_bits = heads * tracks * sectors / cluster_size; allocation_bitmap_lsns = (allocation_bitmap_bits / 8 + sector_bytes - 1) / sector_bytes; format_flags = ((heads > 1) ? 0x01 : 0x00) | ((tracks > 40) ? 0x02 : 0x00); memset(&header[0], 0, sector_bytes); place_integer_be(&header[0], 0, 3, heads * tracks * sectors); place_integer_be(&header[0], 3, 1, sectors); place_integer_be(&header[0], 4, 2, (allocation_bitmap_bits + 7) / 8); place_integer_be(&header[0], 6, 2, cluster_size); place_integer_be(&header[0], 8, 3, 1 + allocation_bitmap_lsns); place_integer_be(&header[0], 11, 2, owner_id); place_integer_be(&header[0], 13, 1, attributes); place_integer_be(&header[0], 14, 2, disk_id); place_integer_be(&header[0], 16, 1, format_flags); place_integer_be(&header[0], 17, 2, sectors); place_string(&header[0], 31, 32, title); place_integer_be(&header[0], 103, 2, sector_bytes / 256); /* path descriptor options */ place_integer_be(&header[0], 0x3f+0x00, 1, 1); /* device class */ place_integer_be(&header[0], 0x3f+0x01, 1, 1); /* drive number */ place_integer_be(&header[0], 0x3f+0x03, 1, 0x20); /* device type */ place_integer_be(&header[0], 0x3f+0x04, 1, 1); /* density capability */ place_integer_be(&header[0], 0x3f+0x05, 2, tracks); /* number of tracks */ place_integer_be(&header[0], 0x3f+0x07, 1, heads); /* number of sides */ place_integer_be(&header[0], 0x3f+0x09, 2, sectors); /* sectors per track */ place_integer_be(&header[0], 0x3f+0x0b, 2, sectors); /* sectors on track zero */ place_integer_be(&header[0], 0x3f+0x0d, 1, 3); /* sector interleave factor */ place_integer_be(&header[0], 0x3f+0x0e, 1, 8); /* default sectors per allocation */ err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id, 0, &header[0], sector_bytes, 0); /* TODO: pass ddam argument from imgtool */ if (err) goto done; total_allocated_sectors = 1 + allocation_bitmap_lsns + 1 + 7; for (i = 0; i < allocation_bitmap_lsns; i++) { memset(&header[0], 0x00, sector_bytes); if (total_allocated_sectors > (8 * 256)) { memset(&header[0], 0xff, sector_bytes); total_allocated_sectors -= (8 * 256); } else if (total_allocated_sectors > 1 ) { int offset; UINT8 mask; while( total_allocated_sectors >= 0 ) { offset = total_allocated_sectors / 8; mask = 1 << (7 - ( total_allocated_sectors % 8 ) ); header[offset] |= mask; total_allocated_sectors--; } } err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 1 + i, 0, &header[0], sector_bytes, 0); /* TODO: pass ddam argument from imgtool */ if (err) goto done; } memset(&header[0], 0, sector_bytes); header[0x00] = 0xBF; header[0x01] = 0x00; header[0x02] = 0x00; header[0x03] = (UINT8) ltime->tm_year; header[0x04] = (UINT8) ltime->tm_mon + 1; header[0x05] = (UINT8) ltime->tm_mday; header[0x06] = (UINT8) ltime->tm_hour; header[0x07] = (UINT8) ltime->tm_min; header[0x08] = 0x02; header[0x09] = 0x00; header[0x0A] = 0x00; header[0x0B] = 0x00; header[0x0C] = 0x40; header[0x0D] = (UINT8) (ltime->tm_year % 100); header[0x0E] = (UINT8) ltime->tm_mon; header[0x0F] = (UINT8) ltime->tm_mday; place_integer_be(&header[0], 0x10, 3, 1 + allocation_bitmap_lsns + 1); place_integer_be(&header[0], 0x13, 2, 8); err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 1 + allocation_bitmap_lsns, 0, &header[0], sector_bytes, 0); /* TODO: pass ddam argument from imgtool */ if (err) goto done; memset(&header[0], 0, sector_bytes); header[0x00] = 0x2E; header[0x01] = 0xAE; header[0x1F] = 1 + allocation_bitmap_lsns; header[0x20] = 0xAE; header[0x3F] = 1 + allocation_bitmap_lsns; err = (imgtoolerr_t)floppy_write_sector(imgtool_floppy(img), 0, 0, first_sector_id + 2 + allocation_bitmap_lsns, 0, &header[0], sector_bytes, 0); /* TOOD: pass ddam argument from imgtool */ if (err) goto done; done: return err; }
static imgtoolerr_t bml3_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions) { floperr_t ferr; imgtoolerr_t err; imgtool_image *img = imgtool_partition_image(partition); bml3_diskinfo *info = bml3_get_diskinfo(img); struct bml3_dirent ent, ent2; size_t i; UINT64 sz, read_sz; UINT64 freespace = 0; unsigned char g; unsigned char *gptr; UINT8 granule_count; UINT8 granule_map[MAX_GRANULEMAP_SIZE]; UINT8 eof_buf[MAX_SECTOR_SIZE]; // one-time setup of eof_buf memset(eof_buf, 0, sizeof(eof_buf)); eof_buf[0] = 0x1A; /* can we write to this image? */ if (floppy_is_read_only(imgtool_floppy(img))) return IMGTOOLERR_READONLY; err = bml3_diskimage_freespace(partition, &freespace); if (err) return err; /* is there enough space? */ sz = read_sz = stream_size(sourcef); if (info->variant == 0) { // also need to write EOF sz++; } if (sz > freespace) return IMGTOOLERR_NOSPACE; /* setup our directory entry */ err = prepare_dirent(info->variant, &ent, fname); if (err) return err; ent.ftype = option_resolution_lookup_int(writeoptions, BML3_OPTIONS_FTYPE); ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, BML3_OPTIONS_ASCII)) - 1; gptr = &ent.first_granule; ferr = get_granule_map(img, granule_map, &granule_count); if (ferr) return imgtool_floppy_error(ferr); g = 0x00; do { while (granule_map[g] != 0xff) { g++; if ((g >= granule_count) || (g == 0)) return IMGTOOLERR_UNEXPECTED; /* We should have already verified that there is enough space */ } *gptr = g; gptr = &granule_map[g]; i = MIN(read_sz, info->granule_sectors * info->sector_size); if (i > 0) { err = transfer_to_granule(img, g, i, sourcef); if (err) return err; read_sz -= i; sz -= i; } if (i < info->granule_sectors * info->sector_size && sz > 0) { // write EOF and trailing NULs in the final sector ferr = write_granule(img, g, i, (info->granule_sectors * info->sector_size - i - 1) % info->sector_size + 1, eof_buf); if (ferr) return imgtool_floppy_error(ferr); sz--; i++; } /* Go to next granule */ g++; } while(sz > 0); /* Now that we are done with the file, we need to specify the final entry * in the file allocation table */ *gptr = 0xc0 + ((i + info->sector_size-1) / info->sector_size) - (info->variant == 0 ? 1 : 0); ent.lastsectorbytes = (i - 1) % info->sector_size + 1; /* delete file if it already exists */ err = bml3_diskimage_deletefile(partition, fname); if (err && err != IMGTOOLERR_FILENOTFOUND) return err; /* Now we need to find an empty directory entry */ i = -1; do { ferr = get_bml3_dirent(img, ++i, &ent2); if (ferr) return imgtool_floppy_error(ferr); } while(ent2.fname[0] != '\0' && ent2.fname[0] != -1); ferr = put_bml3_dirent(img, i, &ent); if (ferr) return imgtool_floppy_error(ferr); /* write the granule map back out */ ferr = put_granule_map(img, granule_map, granule_count); if (ferr) return imgtool_floppy_error(ferr); return IMGTOOLERR_SUCCESS; }
static imgtoolerr_t rsdos_diskimage_writefile(imgtool_partition *partition, const char *fname, const char *fork, imgtool_stream *sourcef, option_resolution *writeoptions) { floperr_t ferr; imgtoolerr_t err; imgtool_image *img = imgtool_partition_image(partition); struct rsdos_dirent ent, ent2; size_t i; UINT64 sz; UINT64 freespace = 0; unsigned char g; unsigned char *gptr; UINT8 granule_count; UINT8 granule_map[MAX_GRANULEMAP_SIZE]; /* can we write to this image? */ if (floppy_is_read_only(imgtool_floppy(img))) return IMGTOOLERR_READONLY; err = rsdos_diskimage_freespace(partition, &freespace); if (err) return err; /* is there enough space? */ sz = stream_size(sourcef); if (sz > freespace) return IMGTOOLERR_NOSPACE; /* setup our directory entry */ err = prepare_dirent(&ent, fname); if (err) return err; ent.ftype = option_resolution_lookup_int(writeoptions, RSDOS_OPTIONS_FTYPE); ent.asciiflag = ((UINT8) option_resolution_lookup_int(writeoptions, RSDOS_OPTIONS_ASCII)) - 1; ent.lastsectorbytes_lsb = sz % 256; ent.lastsectorbytes_msb = (((sz % 256) == 0) && (sz > 0)) ? 1 : 0; gptr = &ent.first_granule; ferr = get_granule_map(img, granule_map, &granule_count); if (ferr) return imgtool_floppy_error(ferr); g = 0x00; do { while (granule_map[g] != 0xff) { g++; if ((g >= granule_count) || (g == 0)) return IMGTOOLERR_UNEXPECTED; /* We should have already verified that there is enough space */ } *gptr = g; gptr = &granule_map[g]; i = MIN(sz, (9*256)); err = transfer_to_granule(img, g, i, sourcef); if (err) return err; sz -= i; /* Go to next granule */ g++; } while(sz > 0); /* Now that we are done with the file, we need to specify the final entry * in the file allocation table */ *gptr = 0xc0 + ((i + 255) / 256); /* Now we need to find an empty directory entry */ i = -1; do { ferr = get_rsdos_dirent(img, ++i, &ent2); if (ferr) return imgtool_floppy_error(ferr); } while((ent2.fname[0] != '\0') && strcmp(ent.fname, ent2.fname) && (ent2.fname[0] != -1)); /* delete file if it already exists */ if (ent2.fname[0] && (ent2.fname[0] != -1)) { err = delete_entry(img, &ent2, i); if (err) return err; } ferr = put_rsdos_dirent(img, i, &ent); if (ferr) return imgtool_floppy_error(ferr); /* write the granule map back out */ ferr = put_granule_map(img, granule_map, granule_count); if (ferr) return imgtool_floppy_error(ferr); return IMGTOOLERR_SUCCESS; }