diff --git a/scp.c b/scp.c index f84f36d5..047c9038 100644 --- a/scp.c +++ b/scp.c @@ -805,7 +805,7 @@ const struct scp_error { {"SIGTERM", "SIGTERM received"}, {"FSSIZE", "File System size larger than disk size"}, {"RUNTIME", "Run time limit exhausted"}, - {"INCOMPVHD", "Incompatible VHD Container"}, + {"INCOMPDSK", "Incompatible Disk Container"}, }; const size_t size_map[] = { sizeof (int8), diff --git a/sim_defs.h b/sim_defs.h index d0ff3cdc..065c2574 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -433,7 +433,7 @@ typedef uint32 t_addr; #define SCPE_SIGTERM (SCPE_BASE + 48) /* SIGTERM has been received */ #define SCPE_FSSIZE (SCPE_BASE + 49) /* File System size larger than disk size */ #define SCPE_RUNTIME (SCPE_BASE + 50) /* Run Time Limit Exhausted */ -#define SCPE_INCOMPVHD (SCPE_BASE + 51) /* Incompatible VHD Container */ +#define SCPE_INCOMPDSK (SCPE_BASE + 51) /* Incompatible Disk Container */ #define SCPE_MAX_ERR (SCPE_BASE + 51) /* Maximum SCPE Error Value */ #define SCPE_KFLAG 0x10000000 /* tti data flag */ diff --git a/sim_disk.c b/sim_disk.c index bbfbdf59..f435c4c2 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -86,17 +86,79 @@ Internal routines: #include #endif +/* Newly created SIMH (and possibly RAW) disk containers */ +/* will have this data as the last 512 bytes of the container */ +/* It will not be considered part of the data in the container */ +/* Previously existing containers will have this appended to */ +/* the end of the container if they are opened for write */ +struct simh_disk_footer { + uint8 Signature[4]; /* must be 'simh' */ + uint8 CreatingSimulator[64]; /* name of simulator */ + uint8 DriveType[16]; + uint32 SectorSize; + uint32 SectorCount; + uint32 TransferElementSize; + uint8 CreationTime[28]; /* Result of ctime() */ + uint8 FooterVersion; /* Initially 0 */ + uint8 AccessFormat; /* 1 - SIMH, 2 - RAW */ + uint8 Reserved[382]; /* Currently unused */ + uint32 Checksum; /* CRC32 of the prior 508 bytes */ + }; + +/* OS Independent Disk Virtual Disk (VHD) I/O support */ + +#if (defined (VMS) && !(defined (__ALPHA) || defined (__ia64))) +#define DONT_DO_VHD_SUPPORT /* VAX/VMS compilers don't have 64 bit integers */ +#endif + +#if defined(_WIN32) || defined (__ALPHA) || defined (__ia64) || defined (VMS) +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ +#endif +#endif +#ifndef __BYTE_ORDER__ +#define __BYTE_ORDER__ UNKNOWN +#endif +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +static uint32 +NtoHl(uint32 value) +{ +uint8 *l = (uint8 *)&value; +return (uint32)l[3] | ((uint32)l[2]<<8) | ((uint32)l[1]<<16) | ((uint32)l[0]<<24); +} +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +static uint32 +NtoHl(uint32 value) +{ +return value; +} +#else +static uint32 +NtoHl(uint32 value) +{ +uint8 *l = (uint8 *)&value; + +if (sim_end) + return l[3] | (l[2]<<8) | (l[1]<<16) | (l[0]<<24); +return value; +} +#endif + struct disk_context { + t_offset container_size; /* Size of the data portion (of the pseudo disk) */ DEVICE *dptr; /* Device for unit (access to debug flags) */ uint32 dbit; /* debugging bit */ uint32 sector_size; /* Disk Sector Size (of the pseudo disk) */ uint32 capac_factor; /* Units of Capacity (8 = quadword, 2 = word, 1 = byte) */ uint32 xfer_element_size; /* Disk Bus Transfer size (1 - byte, 2 - word, 4 - longword) */ uint32 storage_sector_size;/* Sector size of the containing storage */ + uint32 removable; /* Removable device flag */ uint32 is_cdrom; /* Host system CDROM Device */ uint32 media_removed; /* Media not available flag */ uint32 auto_format; /* Format determined dynamically */ + struct simh_disk_footer + *footer; #if defined _WIN32 HANDLE disk_handle; /* OS specific Raw device handle */ #endif @@ -276,7 +338,7 @@ static t_stat sim_vhd_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt * static t_stat sim_vhd_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects); static t_stat sim_vhd_disk_clearerr (UNIT *uptr); static t_stat sim_vhd_disk_set_dtype (FILE *f, const char *dtype, uint32 SectorSize, uint32 xfer_element_size); -static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size); +static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size, char sim_name[64]); static t_stat sim_os_disk_implemented_raw (void); static FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmode); static int sim_os_disk_close_raw (FILE *f); @@ -285,7 +347,9 @@ static t_offset sim_os_disk_size_raw (FILE *f); static t_stat sim_os_disk_unload_raw (FILE *f); static t_bool sim_os_disk_isavailable_raw (FILE *f); static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects); +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_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes); 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 *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize); @@ -451,22 +515,13 @@ return (uptr->flags & DKUF_WRP)? TRUE: FALSE; t_offset sim_disk_size (UNIT *uptr) { +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; t_offset physical_size, filesystem_size; t_bool saved_quiet = sim_quiet; -switch (DK_GET_FMT (uptr)) { /* case on format */ - case DKUF_F_STD: /* SIMH format */ - physical_size = sim_fsize_ex (uptr->fileref); - break; - case DKUF_F_VHD: /* VHD format */ - physical_size = sim_vhd_disk_size (uptr->fileref); - break; - case DKUF_F_RAW: /* Raw Physical Disk Access */ - physical_size = sim_os_disk_size_raw (uptr->fileref); - break; - default: - return (t_offset)-1; - } +if ((uptr->flags & UNIT_ATT) == 0) + return (t_offset)-1; +physical_size = ctx->container_size; sim_quiet = TRUE; filesystem_size = get_filesystem_size (uptr); sim_quiet = saved_quiet; @@ -2024,6 +2079,98 @@ for (i = 0; checks[i] != NULL; i++) { return ret_val; } +static t_stat get_disk_footer (UNIT *uptr) +{ +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; +struct simh_disk_footer *f = (struct simh_disk_footer *)calloc (1, sizeof (*f)); +t_offset container_size; +t_offset sim_fsize_ex (FILE *fptr); +uint32 bytesread; + +if (f == NULL) + return SCPE_MEM; +switch (DK_GET_FMT (uptr)) { /* case on format */ + case DKUF_F_STD: /* SIMH format */ + container_size = sim_fsize_ex (uptr->fileref); + if ((container_size != (t_offset)-1) && (container_size > sizeof (*f)) && + (sim_fseeko (uptr->fileref, container_size - sizeof (*f), SEEK_SET) == 0) && + (sizeof (*f) == sim_fread (f, 1, sizeof (*f), uptr->fileref))) + break; + free (f); + f = NULL; + break; + case DKUF_F_RAW: /* RAW format */ + container_size = sim_os_disk_size_raw (uptr->fileref); + if ((container_size != (t_offset)-1) && (container_size > sizeof (*f)) && + (sim_os_disk_read (uptr, container_size - sizeof (*f), (uint8 *)f, &bytesread, sizeof (*f)) == SCPE_OK) && + (bytesread == sizeof (*f))) + break; + free (f); + f = NULL; + break; + case DKUF_F_VHD: /* VHD format */ + memcpy (f->Signature, "simh", 4); + strncpy ((char *)f->DriveType, sim_vhd_disk_get_dtype (uptr->fileref, &f->SectorSize, &f->TransferElementSize, (char *)f->CreatingSimulator), sizeof (f->DriveType)); + container_size = sim_vhd_disk_size (uptr->fileref); + f->SectorCount = (uint32)(container_size / f->SectorSize); + f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum))); + break; + } +if (f) { + if (f->Checksum != NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum)))) { + free (f); + f = NULL; + } + else { + ctx->footer = f; + container_size -= sizeof (*f); + } + } +ctx->container_size = container_size; +return SCPE_OK; +} + +static t_stat store_disk_footer (UNIT *uptr, const char *dtype) +{ +DEVICE *dptr; +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; +struct simh_disk_footer *f; +time_t now = time (NULL); +t_offset total_sectors; + +if ((dptr = find_dev_from_unit (uptr)) == NULL) + return SCPE_NOATT; +if (uptr->flags & UNIT_RO) + return SCPE_RO; +f = (struct simh_disk_footer *)calloc (1, sizeof (*f)); +f->AccessFormat = DK_GET_FMT (uptr); +total_sectors = (((t_offset)uptr->capac) * ctx->capac_factor * ((dptr->flags & DEV_SECTORS) ? 512 : 1)) / ctx->sector_size; +memcpy (f->Signature, "simh", 4); +strncpy ((char *)f->CreatingSimulator, sim_name, sizeof (f->CreatingSimulator)); +strncpy ((char *)f->DriveType, dtype, sizeof (f->DriveType)); +f->SectorSize = NtoHl (ctx->sector_size); +f->SectorCount = NtoHl ((uint32)total_sectors); +f->TransferElementSize = NtoHl (ctx->xfer_element_size); +strncpy ((char*)f->CreationTime, ctime (&now), sizeof (f->CreationTime)); +f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum))); +free (ctx->footer); +ctx->footer = f; +switch (f->AccessFormat) { + case DKUF_F_STD: /* SIMH format */ + sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET); + sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref); + break; + case DKUF_F_VHD: /* VHD format */ + break; + case DKUF_F_RAW: /* Raw Physical Disk Access */ + sim_os_disk_write (uptr, total_sectors * ctx->sector_size, (uint8 *)f, NULL, sizeof (*f)); + break; + default: + break; + } +return SCPE_OK; +} + t_stat sim_disk_attach (UNIT *uptr, const char *cptr, size_t sector_size, size_t xfer_element_size, t_bool dontchangecapac, uint32 dbit, const char *dtype, uint32 pdp11tracksize, int completion_delay) { @@ -2320,31 +2467,40 @@ else { /* normal */ } } /* end if null */ } /* end else */ -if (DK_GET_FMT (uptr) == DKUF_F_VHD) { +if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) { uint32 sector_size, xfer_element_size; + char created_name[64]; + const char *container_dtype = ctx->footer ? (char *)ctx->footer->DriveType : sim_vhd_disk_get_dtype (uptr->fileref, §or_size, &xfer_element_size, created_name); - if ((created) && dtype) + if (ctx->footer) { + sector_size = NtoHl (ctx->footer->SectorSize); + xfer_element_size = NtoHl (ctx->footer->TransferElementSize); + } + if ((DK_GET_FMT (uptr) == DKUF_F_VHD) && created && dtype) sim_vhd_disk_set_dtype (uptr->fileref, dtype, ctx->sector_size, ctx->xfer_element_size); - if (dtype && strcmp (dtype, sim_vhd_disk_get_dtype (uptr->fileref, §or_size, &xfer_element_size))) { + if (dtype) { char cmd[32]; t_stat r = SCPE_OK; if (((sector_size == 0) || (sector_size == ctx->sector_size)) && ((xfer_element_size == 0) || (xfer_element_size == ctx->xfer_element_size))) { - sprintf (cmd, "%s%d %s", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL)); + sprintf (cmd, "%s%d %s", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL, NULL)); r = set_cmd (0, cmd); if (r != SCPE_OK) - r = sim_messagef (r, "Can't set %s%d to drive type %s\n", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL)); + r = sim_messagef (r, "Can't set %s%d to drive type %s\n", dptr->name, (int)(uptr-dptr->units), sim_vhd_disk_get_dtype (uptr->fileref, NULL, NULL, NULL)); } else - r = sim_messagef (SCPE_INCOMPVHD, "VHD incompatible with %s simulator\n", sim_name); + r = sim_messagef (SCPE_INCOMPDSK, "Disk created by the %s simulator is incompatible with the %s simulator\n", created_name, sim_name); if (r != SCPE_OK) { + uptr->flags |= UNIT_ATT; sim_disk_detach (uptr); /* report error now */ + sprintf (cmd, "%s%d %s", dptr->name, (int)(uptr-dptr->units), dtype);/* restore original dtype */ + set_cmd (0, cmd); return r; } } } -uptr->flags = uptr->flags | UNIT_ATT; +uptr->flags |= UNIT_ATT; uptr->pos = 0; /* Get Device attributes if they are available */ @@ -2356,8 +2512,8 @@ if ((created) && (!copied)) { uint8 *secbuf = (uint8 *)calloc (128, ctx->sector_size); /* alloc temp sector buf */ /* - On a newly created disk, we write a zero sector to the last and the - first sectors. This serves 3 purposes: + On a newly created disk, we write zeros to the whole disk. + This serves 3 purposes: 1) it avoids strange allocation delays writing newly allocated storage at the end of the disk during simulator operation 2) it allocates storage for the whole disk at creation time to @@ -2421,7 +2577,6 @@ if ((created) && (!copied)) { if (pdp11tracksize) sim_disk_pdp11_bad_block (uptr, pdp11tracksize, sector_size/sizeof(uint16)); } - if (sim_switches & SWMASK ('K')) { t_stat r = SCPE_OK; t_lba lba, sect; @@ -2471,8 +2626,12 @@ if (sim_switches & SWMASK ('K')) { uptr->dynflags |= UNIT_DISK_CHK; } +if (get_disk_footer (uptr) != SCPE_OK) { + sim_disk_detach (uptr); + return SCPE_OPENERR; + } filesystem_size = get_filesystem_size (uptr); -container_size = size_function (uptr->fileref); +container_size = sim_disk_size (uptr); current_unit_size = ((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1); if (container_size && (container_size != (t_offset)-1)) { if (dontchangecapac) { @@ -2507,14 +2666,17 @@ if (container_size && (container_size != (t_offset)-1)) { return SCPE_FSSIZE; } } - if ((container_size < current_unit_size) && - ((DKUF_F_VHD == DK_GET_FMT (uptr)) || (0 != (uptr->flags & UNIT_RO)))) { + if ((container_size != current_unit_size) && + ((DKUF_F_VHD == DK_GET_FMT (uptr)) || (0 != (uptr->flags & UNIT_RO)) || + (ctx->footer))) { if (!sim_quiet) { int32 saved_switches = sim_switches; + const char *container_dtype = ctx->footer ? (const char *)ctx->footer->DriveType : ""; sim_switches = SWMASK ('R'); uptr->capac = (t_addr)(container_size/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1))); - sim_printf ("%s%d: non expandable disk container '%s' is smaller than simulated device (%s < ", sim_dname (dptr), (int)(uptr-dptr->units), cptr, sprint_capac (dptr, uptr)); + sim_printf ("%s%d: non expandable %s disk container '%s' is %s than simulated device (%s %s ", + sim_dname (dptr), (int)(uptr-dptr->units), container_dtype, cptr, (container_size < current_unit_size) ? "smaller" : "larger", sprint_capac (dptr, uptr), (container_size < current_unit_size) ? "<" : ">"); uptr->capac = saved_capac; sim_printf ("%s)\n", sprint_capac (dptr, uptr)); sim_switches = saved_switches; @@ -2523,7 +2685,7 @@ if (container_size && (container_size != (t_offset)-1)) { return SCPE_OPENERR; } } - else { /* Autosize */ + else { /* Autosize by changing capacity */ if (filesystem_size != (t_offset)-1) { /* Known file system data size AND */ if (filesystem_size > container_size) /* Data size greater than container size? */ container_size = filesystem_size + /* Use file system data size */ @@ -2539,6 +2701,9 @@ if (container_size && (container_size != (t_offset)-1)) { } } +if (dtype && (created || (ctx->footer == NULL))) + store_disk_footer (uptr, dtype); + #if defined (SIM_ASYNCH_IO) sim_disk_set_async (uptr, completion_delay); #endif @@ -2595,6 +2760,7 @@ uptr->dynflags &= ~(UNIT_NO_FIO | UNIT_DISK_CHK); free (uptr->filename); uptr->filename = NULL; uptr->fileref = NULL; +free (ctx->footer); free (uptr->disk_ctx); uptr->disk_ctx = NULL; uptr->io_flush = NULL; @@ -3396,6 +3562,28 @@ _set_errno_from_status (GetLastError ()); return SCPE_IOERR; } +static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes) +{ +OVERLAPPED pos; +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); + +memset (&pos, 0, sizeof (pos)); +pos.Offset = (DWORD)addr; +pos.OffsetHigh = (DWORD)(addr >> 32); +if (ReadFile ((HANDLE)(uptr->fileref), buf, (DWORD)bytes, (LPDWORD)bytesread, &pos)) + return SCPE_OK; +if (ERROR_HANDLE_EOF == GetLastError ()) { /* Return 0's for reads past EOF */ + memset (buf, 0, bytes); + if (bytesread) + *bytesread = bytes; + return SCPE_OK; + } +_set_errno_from_status (GetLastError ()); +return SCPE_IOERR; +} + static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects) { OVERLAPPED pos; @@ -3417,6 +3605,22 @@ _set_errno_from_status (GetLastError ()); return SCPE_IOERR; } +static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes) +{ +OVERLAPPED pos; +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); +if (WriteFile ((HANDLE)(uptr->fileref), buf, bytes, (LPDWORD)byteswritten, &pos)) + return SCPE_OK; +_set_errno_from_status (GetLastError ()); +return SCPE_IOERR; +} + #elif defined (__linux) || defined (__linux__) || defined (__APPLE__)|| defined (__sun) || defined (__sun__) || defined (__hpux) || defined (_AIX) #include @@ -3530,6 +3734,24 @@ if (sectsread) return SCPE_OK; } +static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *rbytesread, uint32 bytes) +{ +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; +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); + +bytesread = pread((int)((long)uptr->fileref), buf, bytes, (off_t)addr); +if (bytesread < 0) { + if (rbytesread) + *rbytesread = 0; + return SCPE_IOERR; + } +if (rbytesread) + *rbytesread = bytesread; +return SCPE_OK; +} + static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects) { struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; @@ -3550,6 +3772,24 @@ if (sectswritten) return SCPE_OK; } +static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *rbyteswritten, uint32 bytes) +{ +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; +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); + +byteswritten = pwrite((int)((long)uptr->fileref), buf, bytes, (off_t)addr); +if (byteswritten < 0) { + if (rbyteswritten) + *rbyteswritten = 0; + return SCPE_IOERR; + } +if (rbyteswritten) + *rbyteswritten = byteswritten; +return SCPE_OK; +} + static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) { if (sector_size) { @@ -3624,11 +3864,21 @@ static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *s return SCPE_NOFNC; } +static t_stat sim_os_disk_read (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *bytesread, uint32 bytes) +{ +return SCPE_NOFNC; +} + static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects) { return SCPE_NOFNC; } +static t_stat sim_os_disk_write (UNIT *uptr, t_offset addr, uint8 *buf, uint32 *byteswritten, uint32 bytes) +{ +return SCPE_NOFNC; +} + static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) { return SCPE_NOFNC; @@ -3708,7 +3958,7 @@ static t_stat sim_vhd_disk_set_dtype (FILE *f, const char *dtype) return SCPE_NOFNC; } -static const char *sim_vhd_disk_get_dtype (FILE *f) +static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size, char sim_name[64]) { return NULL; } @@ -4021,10 +4271,6 @@ typedef struct _VHD_DynamicDiskHeader { #define VHD_DT_Dynamic 3 /* Dynamic hard disk */ #define VHD_DT_Differencing 4 /* Differencing hard disk */ -static uint32 NtoHl(uint32 value); - -static uint64 NtoHll(uint64 value); - typedef struct VHD_IOData *VHDHANDLE; static t_stat ReadFilePosition(FILE *File, void *buf, size_t bufsize, size_t *bytesread, uint64 position) @@ -4080,13 +4326,6 @@ return ~sum; #define __BYTE_ORDER__ UNKNOWN #endif #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ -static uint32 -NtoHl(uint32 value) -{ -uint8 *l = (uint8 *)&value; -return (uint32)l[3] | ((uint32)l[2]<<8) | ((uint32)l[1]<<16) | ((uint32)l[0]<<24); -} - static uint64 NtoHll(uint64 value) { @@ -4096,12 +4335,6 @@ uint32 lowresult = (uint64)l[7] | ((uint64)l[6]<<8) | ((uint64)l[5]<<16) | ((uin return (highresult << 32) | lowresult; } #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -static uint32 -NtoHl(uint32 value) -{ -return value; -} - static uint64 NtoHll(uint64 value) { @@ -4364,7 +4597,7 @@ memset (hVHD->Footer.DriveType, '\0', sizeof hVHD->Footer.DriveType); memcpy (hVHD->Footer.DriveType, dtype, ((1+strlen (dtype)) < sizeof (hVHD->Footer.DriveType)) ? (1+strlen (dtype)) : sizeof (hVHD->Footer.DriveType)); hVHD->Footer.DriveSectorSize = NtoHl (SectorSize); hVHD->Footer.DriveTransferElementSize = NtoHl (xfer_element_size); -strncpy (hVHD->Footer.CreatingSimulator, sim_name, sizeof (hVHD->Footer.CreatingSimulator)); +strncpy ((char *)hVHD->Footer.CreatingSimulator, sim_name, sizeof (hVHD->Footer.CreatingSimulator)); hVHD->Footer.Checksum = 0; hVHD->Footer.Checksum = NtoHl (CalculateVhdFooterChecksum (&hVHD->Footer, sizeof(hVHD->Footer))); @@ -4410,7 +4643,7 @@ if (Status) return SCPE_OK; } -static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size) +static const char *sim_vhd_disk_get_dtype (FILE *f, uint32 *SectorSize, uint32 *xfer_element_size, char sim_name[64]) { VHDHANDLE hVHD = (VHDHANDLE)f; @@ -4418,6 +4651,8 @@ if (SectorSize) *SectorSize = NtoHl (hVHD->Footer.DriveSectorSize); if (xfer_element_size) *xfer_element_size = NtoHl (hVHD->Footer.DriveTransferElementSize); +if (sim_name) + memcpy (sim_name, hVHD->Footer.CreatingSimulator, 64); return (char *)(&hVHD->Footer.DriveType[0]); }