mirror of
https://github.com/simh/simh.git
synced 2026-01-11 23:52:58 +00:00
DISK: Meta data maintenance
- Clean up and avoid crazy extending when autosizing and repair any prior mangling. - Get Media-ID correct after a resize.
This commit is contained in:
parent
c986b9082b
commit
a860d166fc
180
sim_disk.c
180
sim_disk.c
@ -398,6 +398,7 @@ static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *s
|
|||||||
static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes);
|
static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes);
|
||||||
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects);
|
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects);
|
||||||
static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes);
|
static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes);
|
||||||
|
static t_stat sim_os_disk_set_size (UNIT *uptr, t_offset addr);
|
||||||
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom);
|
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom);
|
||||||
static char *HostPathToVhdPath (const char *szHostPath, char *szVhdPath, size_t VhdPathSize);
|
static char *HostPathToVhdPath (const char *szHostPath, char *szVhdPath, size_t VhdPathSize);
|
||||||
static char *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize);
|
static char *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize);
|
||||||
@ -2856,7 +2857,6 @@ static t_stat get_disk_footer (UNIT *uptr, struct disk_context **pctx)
|
|||||||
{
|
{
|
||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
struct simh_disk_footer *f = (struct simh_disk_footer *)calloc (1, sizeof (*f));
|
struct simh_disk_footer *f = (struct simh_disk_footer *)calloc (1, sizeof (*f));
|
||||||
t_offset container_size;
|
|
||||||
t_offset sim_fsize_ex (FILE *fptr);
|
t_offset sim_fsize_ex (FILE *fptr);
|
||||||
uint32 bytesread;
|
uint32 bytesread;
|
||||||
|
|
||||||
@ -2867,18 +2867,18 @@ if (pctx != NULL)
|
|||||||
sim_debug_unit (ctx->dbit, uptr, "get_disk_footer(%s)\n", sim_uname (uptr));
|
sim_debug_unit (ctx->dbit, uptr, "get_disk_footer(%s)\n", sim_uname (uptr));
|
||||||
switch (DK_GET_FMT (uptr)) { /* case on format */
|
switch (DK_GET_FMT (uptr)) { /* case on format */
|
||||||
case DKUF_F_STD: /* SIMH format */
|
case DKUF_F_STD: /* SIMH format */
|
||||||
container_size = sim_fsize_ex (uptr->fileref);
|
ctx->container_size = sim_fsize_ex (uptr->fileref);
|
||||||
if ((container_size != (t_offset)-1) && (container_size > (t_offset)sizeof (*f)) &&
|
if ((ctx->container_size != (t_offset)-1) && (ctx->container_size > (t_offset)sizeof (*f)) &&
|
||||||
(sim_fseeko (uptr->fileref, container_size - sizeof (*f), SEEK_SET) == 0) &&
|
(sim_fseeko (uptr->fileref, ctx->container_size - sizeof (*f), SEEK_SET) == 0) &&
|
||||||
(sizeof (*f) == sim_fread (f, 1, sizeof (*f), uptr->fileref)))
|
(sizeof (*f) == sim_fread (f, 1, sizeof (*f), uptr->fileref)))
|
||||||
break;
|
break;
|
||||||
free (f);
|
free (f);
|
||||||
f = NULL;
|
f = NULL;
|
||||||
break;
|
break;
|
||||||
case DKUF_F_RAW: /* RAW format */
|
case DKUF_F_RAW: /* RAW format */
|
||||||
container_size = sim_os_disk_size_raw (uptr->fileref);
|
ctx->container_size = sim_os_disk_size_raw (uptr->fileref);
|
||||||
if ((container_size != (t_offset)-1) && (container_size > (t_offset)sizeof (*f)) &&
|
if ((ctx->container_size != (t_offset)-1) && (ctx->container_size > (t_offset)sizeof (*f)) &&
|
||||||
(sim_os_disk_read (uptr, container_size - sizeof (*f), (uint8 *)f, &bytesread, sizeof (*f)) == SCPE_OK) &&
|
(sim_os_disk_read (uptr, ctx->container_size - sizeof (*f), (uint8 *)f, &bytesread, sizeof (*f)) == SCPE_OK) &&
|
||||||
(bytesread == sizeof (*f)))
|
(bytesread == sizeof (*f)))
|
||||||
break;
|
break;
|
||||||
free (f);
|
free (f);
|
||||||
@ -2920,10 +2920,9 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
|
|||||||
}
|
}
|
||||||
memset (f->CreationTime, 0, sizeof (f->CreationTime));
|
memset (f->CreationTime, 0, sizeof (f->CreationTime));
|
||||||
strlcpy ((char*)f->CreationTime, ctime (&creation_time), sizeof (f->CreationTime));
|
strlcpy ((char*)f->CreationTime, ctime (&creation_time), sizeof (f->CreationTime));
|
||||||
container_size = sim_vhd_disk_size (uptr->fileref);
|
ctx->container_size = sim_vhd_disk_size (uptr->fileref);
|
||||||
if ((f->SectorSize != 0) && (NtoHl (f->SectorSize) <= 65536)) /* Range check for Coverity sake */
|
if ((f->SectorSize != 0) && (NtoHl (f->SectorSize) <= 65536)) /* Range check for Coverity sake */
|
||||||
f->SectorCount = NtoHl ((uint32)(container_size / NtoHl (f->SectorSize)));
|
f->SectorCount = NtoHl ((uint32)(ctx->container_size / NtoHl (f->SectorSize)));
|
||||||
container_size += sizeof (*f); /* Adjust since it is removed below */
|
|
||||||
f->AccessFormat = DKUF_F_VHD;
|
f->AccessFormat = DKUF_F_VHD;
|
||||||
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
|
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
|
||||||
}
|
}
|
||||||
@ -2939,23 +2938,26 @@ if (f) {
|
|||||||
f = NULL;
|
f = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* We've got a valid footer, but it may need to be corrected or have missing pieces added */
|
if (DK_GET_FMT (uptr) != DKUF_F_VHD) {
|
||||||
if (((f->MediaID == 0) && (((uptr->drvtyp != NULL) ? uptr->drvtyp->MediaId : 0) != 0)) ||
|
DEVICE *dptr = uptr->dptr;
|
||||||
((sim_disk_find_type (uptr, (char *)f->DriveType) != NULL) &&
|
uint32 f_SectorSize = NtoHl (f->SectorSize);
|
||||||
(NtoHl (f->Geometry) != sim_disk_drvtype_geometry (sim_disk_find_type (uptr, (char *)f->DriveType), NtoHl (f->SectorCount)))) ||
|
uint32 f_SectorCount = NtoHl (f->SectorCount);
|
||||||
((NtoHl (f->ElementEncodingSize) == 1) && /* Encoding still 1 and SCSI disk/cdrom drive */
|
t_offset f_Highwater = ((((t_offset)NtoHl (f->Highwater[0])) << 32) | ((t_offset)NtoHl (f->Highwater[1])));
|
||||||
((0 == memcmp (f->DriveType, "RZ", 2)) ||
|
DRVTYP *drvtyp = sim_disk_find_type (uptr, (char *)f->DriveType);
|
||||||
(0 == memcmp (f->DriveType, "RR", 2))))) {
|
|
||||||
f->ElementEncodingSize = NtoHl (2);
|
|
||||||
if ((uptr->flags & UNIT_RO) == 0) {
|
|
||||||
DEVICE *dptr = uptr->dptr;
|
|
||||||
t_addr saved_capac = uptr->capac;
|
|
||||||
uint32 capac_factor = ((dptr->dwidth / dptr->aincr) >= 32) ? 8 : ((dptr->dwidth / dptr->aincr) == 16) ? 2 : 1; /* capacity units (quadword: 8, word: 2, byte: 1) */
|
|
||||||
|
|
||||||
uptr->capac = (t_addr)(((t_offset)NtoHl(f->SectorCount) * NtoHl(f->SectorSize)) / capac_factor);
|
/* We've got a valid footer, but it may need to be corrected or have missing pieces added */
|
||||||
store_disk_footer (uptr, (char *)f->DriveType);
|
if (((f->MediaID == 0) && (((uptr->drvtyp != NULL) ? uptr->drvtyp->MediaId : 0) != 0)) ||
|
||||||
uptr->capac = saved_capac;
|
((sim_disk_find_type (uptr, (char *)f->DriveType) != NULL) &&
|
||||||
*f = *ctx->footer; /* copy updated footer */
|
(NtoHl (f->Geometry) != sim_disk_drvtype_geometry (sim_disk_find_type (uptr, (char *)f->DriveType), NtoHl (f->SectorCount)))) ||
|
||||||
|
((NtoHl (f->ElementEncodingSize) == 1) && /* Encoding still 1 and SCSI disk/cdrom drive */
|
||||||
|
((0 == memcmp (f->DriveType, "RZ", 2)) ||
|
||||||
|
(0 == memcmp (f->DriveType, "RR", 2)))) ||
|
||||||
|
((drvtyp != NULL) && (ctx->container_size != (sizeof (*f) + (((t_offset)drvtyp->size) * drvtyp->sectsize))))) {
|
||||||
|
f->ElementEncodingSize = NtoHl (2);
|
||||||
|
ctx->footer = f;
|
||||||
|
if ((uptr->flags & UNIT_RO) == 0)
|
||||||
|
store_disk_footer (uptr, (char *)f->DriveType);
|
||||||
|
f = ctx->footer; /* Get possibly updated metadata footer */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((uptr->flags & UNIT_RO) == 0) {
|
if ((uptr->flags & UNIT_RO) == 0) {
|
||||||
@ -2984,12 +2986,9 @@ if (f) {
|
|||||||
free (filename);
|
free (filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (ctx->footer);
|
|
||||||
ctx->footer = f;
|
|
||||||
if (NtoHl (f->MediaID) != 0)
|
if (NtoHl (f->MediaID) != 0)
|
||||||
ctx->media_id = NtoHl (f->MediaID);
|
ctx->media_id = NtoHl (f->MediaID);
|
||||||
ctx->highwater = (((t_offset)NtoHl (f->Highwater[0])) << 32) | ((t_offset)NtoHl (f->Highwater[1]));
|
ctx->highwater = (((t_offset)NtoHl (f->Highwater[0])) << 32) | ((t_offset)NtoHl (f->Highwater[1]));
|
||||||
container_size -= sizeof (*f);
|
|
||||||
sim_debug_unit (ctx->dbit, uptr, "Footer: %s - %s\n"
|
sim_debug_unit (ctx->dbit, uptr, "Footer: %s - %s\n"
|
||||||
" Simulator: %s\n"
|
" Simulator: %s\n"
|
||||||
" DriveType: %s\n"
|
" DriveType: %s\n"
|
||||||
@ -3015,19 +3014,20 @@ if (f) {
|
|||||||
" HighwaterSector: %u\n", (uint32)(ctx->highwater/ctx->sector_size));
|
" HighwaterSector: %u\n", (uint32)(ctx->highwater/ctx->sector_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sim_debug_unit (ctx->dbit, uptr, "Container Size: %u sectors %u bytes each\n", (uint32)(container_size/ctx->sector_size), ctx->sector_size);
|
sim_debug_unit (ctx->dbit, uptr, "Container Size: %u sectors %u bytes each\n", (uint32)(ctx->container_size/ctx->sector_size), ctx->sector_size);
|
||||||
ctx->container_size = container_size;
|
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_stat store_disk_footer (UNIT *uptr, const char *dtype)
|
static t_stat store_disk_footer (UNIT *uptr, const char *dtype)
|
||||||
{
|
{
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
|
DRVTYP *drvtyp;
|
||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
struct stat statb;
|
struct stat statb;
|
||||||
struct simh_disk_footer *f;
|
struct simh_disk_footer *f;
|
||||||
struct simh_disk_footer *old_f = ctx->footer;
|
struct simh_disk_footer *old_f = ctx->footer;
|
||||||
time_t now = time (NULL);
|
time_t now = time (NULL);
|
||||||
|
t_bool Fixed = FALSE;
|
||||||
t_offset total_sectors;
|
t_offset total_sectors;
|
||||||
t_offset highwater;
|
t_offset highwater;
|
||||||
|
|
||||||
@ -3039,7 +3039,15 @@ if (sim_stat (uptr->filename, &statb))
|
|||||||
memset (&statb, 0, sizeof (statb));
|
memset (&statb, 0, sizeof (statb));
|
||||||
f = (struct simh_disk_footer *)calloc (1, sizeof (*f));
|
f = (struct simh_disk_footer *)calloc (1, sizeof (*f));
|
||||||
f->AccessFormat = DK_GET_FMT (uptr);
|
f->AccessFormat = DK_GET_FMT (uptr);
|
||||||
total_sectors = (((t_offset)uptr->capac) * ctx->capac_factor * ((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)) / ctx->sector_size;
|
drvtyp = sim_disk_find_type (uptr, dtype);
|
||||||
|
if ((drvtyp != NULL) &&
|
||||||
|
((drvtyp->flags & DRVFL_SETSIZE) == 0)) {
|
||||||
|
if ((old_f != NULL) && (NtoHl (old_f->SectorCount) != drvtyp->size))
|
||||||
|
Fixed = TRUE;
|
||||||
|
uptr->capac = drvtyp->size * drvtyp->sectsize * ctx->capac_factor / ((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1);
|
||||||
|
total_sectors = ((t_offset)uptr->capac) / ((dptr->flags & DEV_SECTORS) ? 1 : ctx->sector_size);
|
||||||
|
}
|
||||||
|
total_sectors = (drvtyp != NULL) ? (t_offset)drvtyp->size : (((t_offset)uptr->capac) * ctx->capac_factor * ((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)) / ctx->sector_size;
|
||||||
memcpy (f->Signature, "simh", 4);
|
memcpy (f->Signature, "simh", 4);
|
||||||
f->FooterVersion = FOOTER_VERSION;
|
f->FooterVersion = FOOTER_VERSION;
|
||||||
memset (f->CreatingSimulator, 0, sizeof (f->CreatingSimulator));
|
memset (f->CreatingSimulator, 0, sizeof (f->CreatingSimulator));
|
||||||
@ -3053,30 +3061,73 @@ memset (f->CreationTime, 0, sizeof (f->CreationTime));
|
|||||||
strlcpy ((char*)f->CreationTime, ctime (&now), sizeof (f->CreationTime));
|
strlcpy ((char*)f->CreationTime, ctime (&now), sizeof (f->CreationTime));
|
||||||
memset (f->DeviceName, 0, sizeof (f->DeviceName));
|
memset (f->DeviceName, 0, sizeof (f->DeviceName));
|
||||||
strlcpy ((char*)f->DeviceName, dptr->name, sizeof (f->DeviceName));
|
strlcpy ((char*)f->DeviceName, dptr->name, sizeof (f->DeviceName));
|
||||||
f->MediaID = (uptr->drvtyp != NULL) ? NtoHl (uptr->drvtyp->MediaId) : 0;
|
f->MediaID = (drvtyp != NULL) ? NtoHl (drvtyp->MediaId) : 0;
|
||||||
f->DataWidth = NtoHl (uptr->dptr->dwidth);
|
f->DataWidth = NtoHl (uptr->dptr->dwidth);
|
||||||
f->Geometry = NtoHl (sim_disk_drvtype_geometry (sim_disk_find_type (uptr, (char *)f->DriveType), (uint32)total_sectors));
|
if ((old_f != NULL) && ((old_f->Highwater[0] != 0) || (old_f->Highwater[1] != 0)))
|
||||||
highwater = sim_fsize_name_ex (uptr->filename);
|
highwater = ((t_offset)NtoHl (old_f->Highwater[1])) | (((t_offset)NtoHl (old_f->Highwater[0])) << 32);
|
||||||
/* Align Initial Highwater to a sector boundary */
|
else {
|
||||||
highwater = ((highwater + ctx->sector_size - 1) / ctx->sector_size) * ctx->sector_size;
|
highwater = sim_fsize_name_ex (uptr->filename);
|
||||||
|
/* Align Initial Highwater to a sector boundary */
|
||||||
|
highwater = ((highwater + ctx->sector_size - 1) / ctx->sector_size) * ctx->sector_size;
|
||||||
|
}
|
||||||
|
if ((old_f != NULL) || (highwater > (total_sectors * ctx->sector_size))) {
|
||||||
|
if ((old_f != NULL) && (highwater != (NtoHl (old_f->SectorCount) * ctx->sector_size)))
|
||||||
|
highwater -= sizeof (*old_f);
|
||||||
|
if ((drvtyp != NULL) && ((drvtyp->flags & DRVFL_SETSIZE) != 0)) { /* Settable size meta data fixup */
|
||||||
|
total_sectors = highwater / ctx->sector_size;
|
||||||
|
f->SectorCount = NtoHl ((uint32)total_sectors);
|
||||||
|
Fixed = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
f->Highwater[0] = NtoHl ((uint32)(highwater >> 32));
|
f->Highwater[0] = NtoHl ((uint32)(highwater >> 32));
|
||||||
f->Highwater[1] = NtoHl ((uint32)(highwater & 0xFFFFFFFF));
|
f->Highwater[1] = NtoHl ((uint32)(highwater & 0xFFFFFFFF));
|
||||||
|
f->Geometry = NtoHl (sim_disk_drvtype_geometry (drvtyp, (uint32)total_sectors));
|
||||||
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
|
f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)));
|
||||||
|
uptr->capac = ((dptr->flags & DEV_SECTORS) != 0) ? (t_addr)NtoHl (f->SectorCount) : (t_addr)NtoHl (f->SectorCount) * ctx->sector_size;
|
||||||
|
ctx->container_size = (t_offset)(NtoHl (f->SectorCount)) * ctx->sector_size;
|
||||||
|
ctx->highwater = highwater;
|
||||||
if ((old_f != NULL) &&
|
if ((old_f != NULL) &&
|
||||||
(f->DataWidth == old_f->DataWidth) &&
|
(f->DataWidth == old_f->DataWidth) &&
|
||||||
(f->SectorSize == old_f->SectorSize) &&
|
(f->SectorSize == old_f->SectorSize) &&
|
||||||
|
(f->SectorCount == old_f->SectorCount) &&
|
||||||
(f->MediaID == old_f->MediaID) &&
|
(f->MediaID == old_f->MediaID) &&
|
||||||
(f->ElementEncodingSize == old_f->ElementEncodingSize) &&
|
(f->ElementEncodingSize == old_f->ElementEncodingSize) &&
|
||||||
(f->Geometry == old_f->Geometry) &&
|
(f->Geometry == old_f->Geometry) &&
|
||||||
(f->FooterVersion == old_f->FooterVersion)) /* Unchanged? */
|
(f->FooterVersion == old_f->FooterVersion)) { /* Unchanged? */
|
||||||
free(f);
|
free(f);
|
||||||
else {
|
}
|
||||||
|
else { /* meta data changed or created */
|
||||||
|
sim_debug_unit (ctx->dbit, uptr, "Updating %sFooter: %s - %s\n"
|
||||||
|
" Simulator: %s\n"
|
||||||
|
" DriveType: %s\n"
|
||||||
|
" SectorSize: %u\n"
|
||||||
|
" SectorCount: %u\n"
|
||||||
|
" TransferElementSize: %s\n"
|
||||||
|
" FooterVersion: %u\n"
|
||||||
|
" AccessFormat: %u\n"
|
||||||
|
" CreationTime: %s",
|
||||||
|
Fixed ? "after fixing " : "",
|
||||||
|
sim_uname (uptr), uptr->filename,
|
||||||
|
f->CreatingSimulator, f->DriveType, NtoHl(f->SectorSize), NtoHl (f->SectorCount),
|
||||||
|
_disk_tranfer_encoding (NtoHl (f->ElementEncodingSize)), f->FooterVersion, f->AccessFormat, f->CreationTime);
|
||||||
|
if (f->DeviceName[0] != '\0')
|
||||||
|
sim_debug_unit (ctx->dbit, uptr,
|
||||||
|
" DeviceName: %s\n", (char *)f->DeviceName);
|
||||||
|
if (f->DataWidth != 0)
|
||||||
|
sim_debug_unit (ctx->dbit, uptr,
|
||||||
|
" DataWidth: %d bits\n", NtoHl(f->DataWidth));
|
||||||
|
if (f->MediaID != 0)
|
||||||
|
sim_debug_unit (ctx->dbit, uptr,
|
||||||
|
" MediaID: 0x%08X (%s)\n", NtoHl(f->MediaID), sim_disk_decode_mediaid (NtoHl(f->MediaID)));
|
||||||
|
sim_debug_unit (ctx->dbit, uptr,
|
||||||
|
" HighwaterSector: %u\n", (uint32)(ctx->highwater/ctx->sector_size));
|
||||||
free (ctx->footer);
|
free (ctx->footer);
|
||||||
ctx->footer = f;
|
ctx->footer = f;
|
||||||
switch (f->AccessFormat) {
|
switch (f->AccessFormat) {
|
||||||
case DKUF_F_STD: /* SIMH format */
|
case DKUF_F_STD: /* SIMH format */
|
||||||
if (sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET) == 0) {
|
if (sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET) == 0) {
|
||||||
sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref);
|
sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref);
|
||||||
|
sim_set_fsize ((FILE *)uptr->fileref, (t_addr)(total_sectors * ctx->sector_size + sizeof (*f)));
|
||||||
fclose ((FILE *)uptr->fileref);
|
fclose ((FILE *)uptr->fileref);
|
||||||
sim_set_file_times (uptr->filename, statb.st_atime, statb.st_mtime);
|
sim_set_file_times (uptr->filename, statb.st_atime, statb.st_mtime);
|
||||||
uptr->fileref = sim_fopen (uptr->filename, "rb+");
|
uptr->fileref = sim_fopen (uptr->filename, "rb+");
|
||||||
@ -3086,6 +3137,7 @@ else {
|
|||||||
break;
|
break;
|
||||||
case DKUF_F_RAW: /* Raw Physical Disk Access */
|
case DKUF_F_RAW: /* Raw Physical Disk Access */
|
||||||
sim_os_disk_write (uptr, total_sectors * ctx->sector_size, (uint8 *)f, NULL, sizeof (*f));
|
sim_os_disk_write (uptr, total_sectors * ctx->sector_size, (uint8 *)f, NULL, sizeof (*f));
|
||||||
|
sim_os_disk_set_size (uptr, (t_offset)(total_sectors * ctx->sector_size + sizeof (*f)));
|
||||||
sim_os_disk_close_raw (uptr->fileref);
|
sim_os_disk_close_raw (uptr->fileref);
|
||||||
sim_set_file_times (uptr->filename, statb.st_atime, statb.st_mtime);
|
sim_set_file_times (uptr->filename, statb.st_atime, statb.st_mtime);
|
||||||
uptr->fileref = sim_os_disk_open_raw (uptr->filename, "rb+");
|
uptr->fileref = sim_os_disk_open_raw (uptr->filename, "rb+");
|
||||||
@ -3127,7 +3179,7 @@ if (ctx->highwater <= footer_highwater)
|
|||||||
|
|
||||||
if (sim_stat (uptr->filename, &statb))
|
if (sim_stat (uptr->filename, &statb))
|
||||||
memset (&statb, 0, sizeof (statb));
|
memset (&statb, 0, sizeof (statb));
|
||||||
total_sectors = (((t_offset)uptr->capac) * ctx->capac_factor * ((dptr->flags & DEV_SECTORS) ? 512 : 1)) / ctx->sector_size;
|
total_sectors = (((t_offset)uptr->capac) * ctx->capac_factor * ((dptr->flags & DEV_SECTORS) ? ctx->sector_size : 1)) / ctx->sector_size;
|
||||||
highwater = ctx->highwater;
|
highwater = ctx->highwater;
|
||||||
f->Highwater[0] = NtoHl ((uint32)(highwater >> 32));
|
f->Highwater[0] = NtoHl ((uint32)(highwater >> 32));
|
||||||
f->Highwater[1] = NtoHl ((uint32)(highwater & 0xFFFFFFFF));
|
f->Highwater[1] = NtoHl ((uint32)(highwater & 0xFFFFFFFF));
|
||||||
@ -4012,6 +4064,8 @@ if (container_size && (container_size != (t_offset)-1) &&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((uptr->drvtyp != NULL) && (ctx != NULL))
|
||||||
|
ctx->media_id = uptr->drvtyp->MediaId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uptr->flags & UNIT_RO) == 0) { /* Opened Read/Write? */
|
if ((uptr->flags & UNIT_RO) == 0) { /* Opened Read/Write? */
|
||||||
@ -4982,7 +5036,7 @@ static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *b
|
|||||||
OVERLAPPED pos;
|
OVERLAPPED pos;
|
||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
|
|
||||||
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_read(unit=%d, addr=0x%X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)addr, bytes);
|
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_read(unit=%d, addr=0x%X%08X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)(addr >> 32), (uint32)addr, bytes);
|
||||||
|
|
||||||
memset (&pos, 0, sizeof (pos));
|
memset (&pos, 0, sizeof (pos));
|
||||||
pos.Offset = (DWORD)addr;
|
pos.Offset = (DWORD)addr;
|
||||||
@ -5039,12 +5093,31 @@ static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *
|
|||||||
OVERLAPPED pos;
|
OVERLAPPED pos;
|
||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
|
|
||||||
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_write(unit=%d, lba=0x%X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)addr, bytes);
|
memset (&pos, 0, sizeof (pos));
|
||||||
|
pos.Offset = (DWORD)addr;
|
||||||
|
pos.OffsetHigh = (DWORD)(addr >> 32);
|
||||||
|
|
||||||
|
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_write(unit=%d, addr=0x%X%08X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)pos.OffsetHigh, (uint32)pos.Offset, bytes);
|
||||||
|
|
||||||
|
if (WriteFile ((HANDLE)(uptr->fileref), buf, bytes, (LPDWORD)byteswritten, &pos))
|
||||||
|
return SCPE_OK;
|
||||||
|
_set_errno_from_status (GetLastError ());
|
||||||
|
return SCPE_IOERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static t_stat sim_os_disk_set_size (UNIT *uptr, t_offset addr)
|
||||||
|
{
|
||||||
|
OVERLAPPED pos;
|
||||||
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
|
|
||||||
memset (&pos, 0, sizeof (pos));
|
memset (&pos, 0, sizeof (pos));
|
||||||
pos.Offset = (DWORD)addr;
|
pos.Offset = (DWORD)addr;
|
||||||
pos.OffsetHigh = (DWORD)(addr >> 32);
|
pos.OffsetHigh = (DWORD)(addr >> 32);
|
||||||
if (WriteFile ((HANDLE)(uptr->fileref), buf, bytes, (LPDWORD)byteswritten, &pos))
|
|
||||||
|
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_set_size(unit=%d, addr=0x%X%08X)\n", (int)(uptr - ctx->dptr->units), (uint32)pos.OffsetHigh, (uint32)pos.Offset);
|
||||||
|
|
||||||
|
if ((INVALID_SET_FILE_POINTER != SetFilePointer ((HANDLE)(uptr->fileref), pos.Offset, &pos.OffsetHigh, FILE_BEGIN)) &&
|
||||||
|
(SetEndOfFile((HANDLE)(uptr->fileref)) != 0))
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
_set_errno_from_status (GetLastError ());
|
_set_errno_from_status (GetLastError ());
|
||||||
return SCPE_IOERR;
|
return SCPE_IOERR;
|
||||||
@ -5182,7 +5255,7 @@ static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *r
|
|||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
ssize_t bytesread;
|
ssize_t bytesread;
|
||||||
|
|
||||||
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_read(unit=%d, addr=0x%X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)addr, bytes);
|
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_read(unit=%d, addr=0x%X%08X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)(addr >> 32), (uint32)addr, bytes);
|
||||||
|
|
||||||
bytesread = pread((int)((long)uptr->fileref), buf, bytes, (off_t)addr);
|
bytesread = pread((int)((long)uptr->fileref), buf, bytes, (off_t)addr);
|
||||||
if (bytesread < 0) {
|
if (bytesread < 0) {
|
||||||
@ -5230,7 +5303,7 @@ static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *
|
|||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
ssize_t byteswritten;
|
ssize_t byteswritten;
|
||||||
|
|
||||||
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_write(unit=%d, addr=0x%X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)addr, bytes);
|
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_write(unit=%d, addr=0x%X%08X, bytes=%u)\n", (int)(uptr - ctx->dptr->units), (uint32)(addr >> 32), (uint32)addr, bytes);
|
||||||
|
|
||||||
if (rbyteswritten)
|
if (rbyteswritten)
|
||||||
*rbyteswritten = 0;
|
*rbyteswritten = 0;
|
||||||
@ -5242,6 +5315,18 @@ if (rbyteswritten)
|
|||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static t_stat sim_os_disk_set_size (UNIT *uptr, t_offset addr)
|
||||||
|
{
|
||||||
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
|
int fd = (int)((long)uptr->fileref);
|
||||||
|
|
||||||
|
sim_debug_unit (ctx->dbit, uptr, "sim_os_disk_set_size(unit=%d, addr=0x%X%08X)\n", (int)(uptr - ctx->dptr->units), (uint32)(addr >> 32), (uint32)addr);
|
||||||
|
|
||||||
|
if (ftruncate (fd, (off_t)addr) == -1)
|
||||||
|
return SCPE_IOERR;
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom)
|
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom)
|
||||||
{
|
{
|
||||||
if (sector_size) {
|
if (sector_size) {
|
||||||
@ -5335,6 +5420,11 @@ static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *
|
|||||||
return SCPE_NOFNC;
|
return SCPE_NOFNC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static t_stat sim_os_disk_set_size (UNIT *uptr, t_offset addr)
|
||||||
|
{
|
||||||
|
return SCPE_NOFNC;
|
||||||
|
}
|
||||||
|
|
||||||
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom)
|
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom)
|
||||||
{
|
{
|
||||||
*sector_size = *removable = *is_cdrom = 0;
|
*sector_size = *removable = *is_cdrom = 0;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user