UINT32 hard_disk_write(struct hard_disk_file *file, UINT32 lbasector, UINT32 numsectors, const void *buffer) { UINT32 hunknum = lbasector / file->hunksectors; UINT32 sectoroffs = lbasector % file->hunksectors; /* for now, just break down multisector writes into single sectors */ if (numsectors > 1) { UINT32 total = 0; while (numsectors--) { if (hard_disk_write(file, lbasector++, 1, (const UINT8 *)buffer + total * file->info.sectorbytes)) total++; else break; } return total; } /* if we haven't cached this hunk, read it now */ if (file->cachehunk != hunknum) { if (!chd_read(file->chd, hunknum, 1, file->cache)) return 0; file->cachehunk = hunknum; } /* copy in the requested data */ memcpy(&file->cache[sectoroffs * file->info.sectorbytes], buffer, file->info.sectorbytes); /* write it back out */ if (chd_write(file->chd, hunknum, 1, file->cache)) return 1; return 0; }
UINT32 hard_disk_write(hard_disk_file *file, UINT32 lbasector, const void *buffer) { UINT32 hunknum = lbasector / file->hunksectors; UINT32 sectoroffs = lbasector % file->hunksectors; chd_error err; /* if we haven't cached this hunk, read it now */ if (file->cachehunk != hunknum) { err = chd_read(file->chd, hunknum, file->cache); if (err != CHDERR_NONE) return 0; file->cachehunk = hunknum; } /* copy in the requested data */ memcpy(&file->cache[sectoroffs * file->info.sectorbytes], buffer, file->info.sectorbytes); /* write it back out */ err = chd_write(file->chd, hunknum, file->cache); return (err == CHDERR_NONE) ? 1 : 0; }
/* imghd_create() Create a MAME HD image */ imgtoolerr_t imghd_create(imgtool_stream *stream, UINT32 hunksize, UINT32 cylinders, UINT32 heads, UINT32 sectors, UINT32 seclen) { imgtoolerr_t err = IMGTOOLERR_SUCCESS; char encoded_image_ref[encoded_image_ref_max_len]; chd_interface interface_save; UINT8 *cache = NULL; chd_file *chd = NULL; int rc; UINT64 logicalbytes; int hunknum, totalhunks; char metadata[256]; /* jump through the hoops as required by the CHD system */ encode_image_ref(stream, encoded_image_ref); chd_save_interface(&interface_save); chd_set_interface(&imgtool_chd_interface); /* sanity check args */ if (hunksize >= 2048) { err = IMGTOOLERR_PARAMCORRUPT; goto done; } if (hunksize <= 0) hunksize = 1024; /* default value */ /* bail if we are read only */ if (stream_isreadonly(stream)) { err = IMGTOOLERR_READONLY; goto done; } /* calculations */ logicalbytes = (UINT64)cylinders * heads * sectors * seclen; /* create the new hard drive */ rc = chd_create(encoded_image_ref, logicalbytes, hunksize, CHDCOMPRESSION_NONE, NULL); if (rc != CHDERR_NONE) { err = map_chd_error(rc); goto done; } /* open the new hard drive */ rc = chd_open(encoded_image_ref, CHD_OPEN_READWRITE, NULL, &chd); if (rc != CHDERR_NONE) { err = map_chd_error(rc); goto done; } /* write the metadata */ sprintf(metadata, HARD_DISK_METADATA_FORMAT, cylinders, heads, sectors, seclen); err = chd_set_metadata(chd, HARD_DISK_METADATA_TAG, 0, metadata, strlen(metadata) + 1); if (rc != CHDERR_NONE) { err = map_chd_error(rc); goto done; } /* alloc and zero buffer */ cache = malloc(hunksize); if (!cache) { err = IMGTOOLERR_OUTOFMEMORY; goto done; } memset(cache, '\0', hunksize); /* zero out every hunk */ totalhunks = (logicalbytes + hunksize - 1) / hunksize; for (hunknum = 0; hunknum < totalhunks; hunknum++) { rc = chd_write(chd, hunknum, cache); if (rc) { err = IMGTOOLERR_WRITEERROR; goto done; } } done: if (cache) free(cache); if (chd) chd_close(chd); chd_set_interface(&interface_save); return err; }