1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-11 23:52:48 +00:00

SCP: Updated to current.

This commit is contained in:
Richard Cornwell 2020-04-13 22:25:15 -04:00
parent 9a63bc521e
commit 188b52454b
7 changed files with 348 additions and 85 deletions

22
scp.c
View File

@ -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),
@ -15380,6 +15380,10 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
t_stat tstat = SCPE_OK;
t_bool was_disabled = ((dptr->flags & DEV_DIS) != 0);
if (DEV_TYPE(dptr) == 0) {
sim_printf ("Skipping %s - non library device type\n", dptr->name);
continue; /* skip unspecified devices */
}
sim_switches = saved_switches;
if (was_disabled)
tstat = set_dev_enbdis (dptr, NULL, 1, NULL);
@ -15405,11 +15409,21 @@ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
default:
break;
}
if (was_disabled)
set_dev_enbdis (dptr, NULL, 0, NULL);
}
if (was_disabled)
set_dev_enbdis (dptr, NULL, 0, NULL);
if (tstat != SCPE_OK)
else
tstat = SCPE_OK; /* can't enable, just skip device */
if (tstat != SCPE_OK) {
stat = tstat;
sim_printf ("%s device tests returned: %d - %s\n", dptr->name, tstat, sim_error_text (tstat));
if (sim_ttisatty()) {
if (get_yn ("Continue with additional tests? [N]", SCPE_STOP) == SCPE_STOP)
break;
}
else
break;
}
}
return stat;
}

2
scp.h
View File

@ -333,7 +333,7 @@ void sim_debug_bits (uint32 dbits, DEVICE* dptr, BITFIELD* bitdefs,
#define _sim_debug_device sim_debug
void sim_debug (uint32 dbits, DEVICE* dptr, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
#define _sim_debug_unit sim_debug_unit
void sim_debug_unit (uint32 dbits, DEVICE* dptr, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
void sim_debug_unit (uint32 dbits, UNIT* uptr, const char *fmt, ...) GCC_FMT_ATTR(3, 4);
#else
void _sim_debug_unit (uint32 dbits, UNIT *uptr, const char* fmt, ...) GCC_FMT_ATTR(3, 4);
void _sim_debug_device (uint32 dbits, DEVICE* dptr, const char* fmt, ...) GCC_FMT_ATTR(3, 4);

View File

@ -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 */

View File

@ -33,6 +33,7 @@
Public routines:
sim_disk_attach attach disk unit
sim_disk_attach_ex attach disk unit extended parameters
sim_disk_detach detach disk unit
sim_disk_attach_help help routine for attaching disks
sim_disk_rdsect read disk sectors
@ -85,17 +86,79 @@ Internal routines:
#include <pthread.h>
#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
@ -275,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);
@ -284,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);
@ -450,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;
@ -2023,6 +2079,102 @@ 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));
if (f->SectorCount == 0) { /* Old format VHD footer */
sim_vhd_disk_set_dtype (uptr->fileref, f->DriveType, ctx->sector_size, ctx->xfer_element_size);
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)
{
@ -2319,31 +2471,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, &sector_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, &sector_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 */
@ -2355,8 +2516,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
@ -2420,7 +2581,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;
@ -2470,8 +2630,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) {
@ -2479,23 +2643,21 @@ if (container_size && (container_size != (t_offset)-1)) {
if (filesystem_size == (t_offset)-1) /* No file system found? */
filesystem_size = container_size; /* Assume full container */
if (filesystem_size != (t_offset)-1) {
const char *drive_type = NULL;
while ((filesystem_size > current_unit_size) &&
((drivetypes ? *drivetypes : NULL) != NULL)) {
if (drivetypes != NULL) {
/* Walk through all potential drive types until we find one the right size */
while (*drivetypes != NULL) {
char cmd[CBUFSIZE];
t_stat st;
uptr->flags &= ~UNIT_ATT; /* temporarily mark as un-attached */
drive_type = *drivetypes;
sprintf (cmd, "%s %s", sim_uname (uptr), *drivetypes);
st = set_cmd (0, cmd);
uptr->flags |= UNIT_ATT; /* restore attached indicator */
if (st == SCPE_OK) {
if (st == SCPE_OK)
current_unit_size = ((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1);
++drivetypes; /* next type */
}
if (current_unit_size >= filesystem_size)
break;
++drivetypes;
}
if (filesystem_size > current_unit_size) {
if (!sim_quiet) {
@ -2508,14 +2670,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;
@ -2524,7 +2689,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 */
@ -2540,6 +2705,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
@ -2596,6 +2764,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;
@ -3397,6 +3566,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;
@ -3418,6 +3609,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 <sys/types.h>
@ -3531,6 +3738,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;
@ -3551,6 +3776,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) {
@ -3625,11 +3868,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;
@ -3709,7 +3962,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;
}
@ -3882,10 +4135,11 @@ typedef struct _VHD_Footer {
uint8 DriveType[16];
uint32 DriveSectorSize;
uint32 DriveTransferElementSize;
uint8 CreatingSimulator[64];
/*
This field contains zeroes. It is 392 bytes in size.
This field contains zeroes. It is 328 bytes in size.
*/
uint8 Reserved[392];
uint8 Reserved[328];
} VHD_Footer;
/*
@ -4021,10 +4275,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 +4330,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 +4339,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,6 +4601,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 ((char *)hVHD->Footer.CreatingSimulator, sim_name, sizeof (hVHD->Footer.CreatingSimulator));
hVHD->Footer.Checksum = 0;
hVHD->Footer.Checksum = NtoHl (CalculateVhdFooterChecksum (&hVHD->Footer, sizeof(hVHD->Footer)));
@ -4409,7 +4647,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;
@ -4417,6 +4655,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]);
}

View File

@ -2478,10 +2478,17 @@ const char *eth_version (void)
static char version[256];
if (!version[0]) {
if (memcmp(pcap_lib_version(), "Npcap", 5))
strlcpy(version, pcap_lib_version(), sizeof(version));
else
snprintf(version, sizeof(version), "Unsupported - %s", pcap_lib_version());
strlcpy(version, pcap_lib_version(), sizeof(version));
if (memcmp(pcap_lib_version(), "Npcap", 5) == 0) {
char maj_min[CBUFSIZE];
char *c = version;
while (*c && !isdigit (*c))
++c;
get_glyph (c, maj_min, ',');
if (strcmp ("0.9990", maj_min) < 0)
snprintf(version, sizeof(version), "Unsupported - %s", pcap_lib_version());
}
}
return version;
#else

View File

@ -688,7 +688,7 @@ return 0;
port = pointer to buffer for IP port (may be NULL), 0 = none
localport
= pointer to buffer for local IP port (may be NULL), 0 = none
result = status (SCPE_OK on complete success or SCPE_ARG if
result = status (0 on complete success or -1 if
parsing can't happen due to bad syntax, a value is
out of range, a result can't fit into a result buffer,
a service name doesn't exist, or a validation name
@ -1018,11 +1018,6 @@ if (!(opt_flags & SIM_SOCK_OPT_DATAGRAM)) {
if (sta == -1)
return sim_err_sock (newsock, "setsockopt KEEPALIVE");
}
if (!(opt_flags & SIM_SOCK_OPT_BLOCKING)) {
sta = sim_setnonblock (newsock); /* set nonblocking */
if (sta == SOCKET_ERROR) /* fcntl error? */
return sim_err_sock (newsock, "setnonblock");
}
sta = connect (newsock, result->ai_addr, result->ai_addrlen);
p_freeaddrinfo (result);
if (sta == SOCKET_ERROR) {

View File

@ -1286,8 +1286,7 @@ for (i = 0; i < mp->lines; i++) { /* check each line in se
snprintf (msg, sizeof (msg) - 1, "tmxr_poll_conn() - establishing outgoing connection to: %s", lp->destination);
tmxr_debug_connect_line (lp, msg);
lp->connecting = sim_connect_sock_ex (lp->datagram ? lp->port : NULL, lp->destination, "localhost", NULL, (lp->datagram ? SIM_SOCK_OPT_DATAGRAM : 0) |
(lp->mp->packet ? SIM_SOCK_OPT_NODELAY : 0) |
SIM_SOCK_OPT_BLOCKING);
(lp->mp->packet ? SIM_SOCK_OPT_NODELAY : 0));
}
}
@ -1358,8 +1357,7 @@ if ((lp->destination) && (!lp->serport)) {
sprintf (msg, "tmxr_reset_ln_ex() - connecting to %s", lp->destination);
tmxr_debug_connect_line (lp, msg);
lp->connecting = sim_connect_sock_ex (lp->datagram ? lp->port : NULL, lp->destination, "localhost", NULL, (lp->datagram ? SIM_SOCK_OPT_DATAGRAM : 0) |
(lp->packet ? SIM_SOCK_OPT_NODELAY : 0) |
SIM_SOCK_OPT_BLOCKING);
(lp->packet ? SIM_SOCK_OPT_NODELAY : 0));
}
}
tmxr_init_line (lp); /* initialize line state */
@ -3078,8 +3076,7 @@ while (*tptr) {
return sim_messagef (SCPE_ARG, "Missing listen port for Datagram socket\n");
}
sock = sim_connect_sock_ex (datagram ? listen : NULL, hostport, "localhost", NULL, (datagram ? SIM_SOCK_OPT_DATAGRAM : 0) |
(packet ? SIM_SOCK_OPT_NODELAY : 0) |
SIM_SOCK_OPT_BLOCKING);
(packet ? SIM_SOCK_OPT_NODELAY : 0));
if (sock != INVALID_SOCKET) {
_mux_detach_line (lp, FALSE, TRUE);
lp->destination = (char *)malloc(1+strlen(hostport));
@ -5455,19 +5452,28 @@ if ((dptr) && (dbits & dptr->dctrl)) {
t_stat tmxr_sock_test (DEVICE *dptr)
{
char cmd[CBUFSIZE];
char cmd[CBUFSIZE], host[CBUFSIZE], port[CBUFSIZE];
int line;
TMXR *tmxr;
TMLN *ln;
int32 tmp1, tmp2;
t_stat stat = SCPE_OK;
SOCKET sock_mux = INVALID_SOCKET;
SOCKET sock_line = INVALID_SOCKET;
SIM_TEST_INIT;
sim_printf ("Testing %s:\n", dptr->name);
SIM_TEST(sim_parse_addr ("", NULL, 0, "localhost", NULL, 0, "1234", NULL) != -1);
SIM_TEST(sim_parse_addr ("", host, 0, "localhost", NULL, 0, "1234", NULL) != -1);
SIM_TEST(sim_parse_addr ("", host, sizeof(host), "localhost", port, 0, "1234", NULL) != -1);
SIM_TEST((sim_parse_addr ("", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"1234")));
SIM_TEST((sim_parse_addr ("localhost:6666", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"6666")));
SIM_TEST(sim_parse_addr ("localhost:66666", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) != -1);
SIM_TEST((sim_parse_addr ("localhost:telnet", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"telnet")));
SIM_TEST((sim_parse_addr ("telnet", host, sizeof(host), "localhost", port, sizeof(port), "1234", NULL) == -1) || (strcmp(host, "localhost")) || (strcmp(port,"telnet")));
dptr->dctrl = 0xFFFFFFFF;
dptr->dctrl &= ~TMXR_DBG_TRC;
sprintf (cmd, "%s -u localhost:65500", dptr->name);
sprintf (cmd, "%s -u localhost:65500;notelnet", dptr->name);
SIM_TEST(attach_cmd (0, cmd));
tmxr = (TMXR *)dptr->units->tmxr;
ln = &tmxr->ldsc[tmxr->lines - 1];
@ -5477,13 +5483,14 @@ if (tmxr->lines > 1) {
for (line=0; line < tmxr->lines; line++)
tmxr->ldsc[line].modem_control = FALSE;
snprintf (cmd + strlen (cmd), sizeof (cmd) - strlen (cmd), ",Line=%d,localhost:65501", tmxr->lines - 1);
snprintf (cmd + strlen (cmd), sizeof (cmd) - strlen (cmd), ",Line=0,connect=localhost:65500");
SIM_TEST(attach_cmd (0, cmd));
sock_line = sim_connect_sock_ex (NULL, "localhost:65501", NULL, NULL, 0);
sim_os_ms_sleep (100);
SIM_TEST((tmxr_poll_conn (tmxr) == tmxr->lines - 1) ? SCPE_OK : SCPE_IERR);
SIM_TEST((((tmp1 = tmxr_poll_conn (tmxr)) == tmxr->lines - 1) || (tmp1 == 1)) ? SCPE_OK : SCPE_IERR);
sock_mux = sim_connect_sock ("", "localhost", "65500");
sim_os_ms_sleep (100);
SIM_TEST((tmxr_poll_conn (tmxr) == 0) ? SCPE_OK : SCPE_IERR);
SIM_TEST(((tmp2 = tmxr_poll_conn (tmxr)) == 0) || (tmp2 == 2) ? SCPE_OK : SCPE_IERR);
show_cmd (0, "MUX");
sim_close_sock (sock_mux);
sock_mux = INVALID_SOCKET;