Generalized the sim_disk layer to support large file disk devices (simh, VHD and RAW formats) with out requiring USE_ADDR64, and enhanced the pdp11_rq device to use this capability.

This commit is contained in:
Mark Pizzolato 2013-03-17 12:02:43 -07:00
parent 60e855807f
commit 2e5b0d54c6
10 changed files with 145 additions and 128 deletions

View file

@ -543,7 +543,7 @@ t_stat sectRead(DISK_INFO *myDisk,
DBG_PRINT(("Reading C:%d/H:%d/S:%d, len=%d, offset=0x%08x" NLP, Cyl, Head, Sector, buflen, sectorFileOffset));
sim_fseek(myDisk->file, sectorFileOffset-1, 0);
sim_fseek(myDisk->file, sectorFileOffset-1, SEEK_SET);
sectRecordType = fgetc(myDisk->file);
switch(sectRecordType) {
@ -642,7 +642,7 @@ t_stat sectWrite(DISK_INFO *myDisk,
sectorFileOffset = myDisk->track[Cyl][Head].sectorOffsetMap[Sector-start_sect];
sim_fseek(myDisk->file, sectorFileOffset-1, 0);
sim_fseek(myDisk->file, sectorFileOffset-1, SEEK_SET);
if (*flags & IMD_DISK_IO_ERROR_GENERAL) {
sectRecordType = SECT_RECORD_UNAVAILABLE;

View file

@ -654,7 +654,7 @@ struct drvtyp {
d##_GPC, d##_XBN, d##_DBN, d##_LBN, \
d##_RCTS, d##_RCTC, d##_RBN, d##_MOD, \
d##_MED, d##_FLGS
#define RQ_SIZE(d) (d##_LBN * RQ_NUMBY)
#define RQ_SIZE(d) d##_LBN
static struct drvtyp drv_tab[] = {
{ RQ_DRV (RX50), "RX50" },
@ -1011,7 +1011,7 @@ DEVICE rq_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach,
&rq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK,
&rq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description
};
@ -1086,7 +1086,7 @@ DEVICE rqb_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach,
&rqb_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK,
&rqb_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description
};
@ -1161,7 +1161,7 @@ DEVICE rqc_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach,
&rqc_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK,
&rqc_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description
};
@ -1236,7 +1236,7 @@ DEVICE rqd_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach,
&rqd_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK,
&rqd_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG | DEV_DISK | DEV_SECTORS,
0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description
};
@ -1915,7 +1915,7 @@ int32 rq_rw_valid (MSC *cp, int32 pkt, UNIT *uptr, uint32 cmd)
uint32 dtyp = GET_DTYPE (uptr->flags); /* get drive type */
uint32 lbn = GETP32 (pkt, RW_LBNL); /* get lbn */
uint32 bc = GETP32 (pkt, RW_BCL); /* get byte cnt */
uint32 maxlbn = (uint32) (uptr->capac / RQ_NUMBY); /* get max lbn */
uint32 maxlbn = (uint32)uptr->capac; /* get max lbn */
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
return (ST_OFL | SB_OFL_NV); /* offl no vol */
@ -2549,7 +2549,7 @@ return;
void rq_putr_unit (MSC *cp, int32 pkt, UNIT *uptr, uint32 lu, t_bool all)
{
uint32 dtyp = GET_DTYPE (uptr->flags); /* get drive type */
uint32 maxlbn = (uint32) (uptr->capac / RQ_NUMBY); /* get max lbn */
uint32 maxlbn = (uint32)uptr->capac; /* get max lbn */
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_putr_unit\n");
@ -2723,7 +2723,7 @@ if (cptr) {
drv_tab[val].lbn = cap;
}
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE);
uptr->capac = ((t_addr) drv_tab[val].lbn) * RQ_NUMBY;
uptr->capac = (t_addr)drv_tab[val].lbn;
return SCPE_OK;
}

View file

@ -20,6 +20,7 @@
RQ has new disk types: RC25, RCF25, RA80
RQ device has a settable controller type (RQDX3, UDA50, KLESI, RUX50)
RQ disks default to Autosize without regard to disk type
RQ disks on PDP11 can have RAUSER size beyond 2GB
DMC11 DDCMP DECnet device simulation from Rob Jarratt. Up to 4 DMC11 devices are supported.
DZ on Unibus systems can have up to 256 ports (default of 32), on
Qbus systems 128 port limit (default of 16).

6
scp.c
View file

@ -2710,6 +2710,10 @@ t_addr mval = kval * kval;
t_addr psize = uptr->capac;
char scale, width;
if (dptr->flags & DEV_SECTORS) {
kval = kval / 512;
mval = mval / 512;
}
if ((dptr->dwidth / dptr->aincr) > 8)
width = 'W';
else width = 'B';
@ -2753,7 +2757,6 @@ if (flag) {
fprintf (st, "\n\t\t%s", sim_snet);
idle_capable = sim_timer_idle_capable (&os_tick_size);
fprintf (st, "\n\t\tIdle/Throttling support is %savailable", ((idle_capable == 0) ? "NOT " : ""));
fprintf (st, "\n\t\t%s", sim_taddr_64 ? "Large File (>2GB) support" : "No Large File support");
if (sim_disk_vhd_support())
fprintf (st, "\n\t\tVirtual Hard Disk (VHD) support");
if (sim_disk_raw_support())
@ -2770,6 +2773,7 @@ if (flag) {
fprintf (st, "\n\tHost Platform:");
fprintf (st, "\n\t\tMemory Access: %s Endian", sim_end ? "Little" : "Big");
fprintf (st, "\n\t\tMemory Pointer Size: %d bits", (int)sizeof(dptr)*8);
fprintf (st, "\n\t\t%s", sim_toffset_64 ? "Large File (>2GB) support" : "No Large File support");
#if defined(__VMS)
fprintf (st, "\n\t\tOS: VMS");
#elif defined(_WIN32)

View file

@ -358,6 +358,7 @@ struct sim_device {
#define DEV_V_DEBUG 3 /* debug capability */
#define DEV_V_TYPE 4 /* Attach type */
#define DEV_S_TYPE 3 /* Width of Type Field */
#define DEV_V_SECTORS 7 /* Unit Capacity is in 512byte sectors */
#define DEV_V_UF_31 12 /* user flags, V3.1 */
#define DEV_V_UF 16 /* user flags */
#define DEV_V_RSV 31 /* reserved */
@ -366,6 +367,7 @@ struct sim_device {
#define DEV_DISABLE (1 << DEV_V_DISABLE) /* device is currently disabled */
#define DEV_DYNM (1 << DEV_V_DYNM) /* device requires call on msize routine to change memory size */
#define DEV_DEBUG (1 << DEV_V_DEBUG) /* device supports SET DEBUG command */
#define DEV_SECTORS (1 << DEV_V_SECTORS) /* capacity is 512 byte sectors */
#define DEV_NET 0 /* Deprecated - meaningless */

View file

@ -265,12 +265,12 @@ if (ctx) {
static t_stat sim_vhd_disk_implemented (void);
static FILE *sim_vhd_disk_open (const char *rawdevicename, const char *openmode);
static FILE *sim_vhd_disk_create (const char *szVHDPath, t_addr desiredsize);
static FILE *sim_vhd_disk_create (const char *szVHDPath, t_offset desiredsize);
static FILE *sim_vhd_disk_create_diff (const char *szVHDPath, const char *szParentVHDPath);
static FILE *sim_vhd_disk_merge (const char *szVHDPath, char **ParentVHD);
static int sim_vhd_disk_close (FILE *f);
static void sim_vhd_disk_flush (FILE *f);
static t_addr sim_vhd_disk_size (FILE *f);
static t_offset sim_vhd_disk_size (FILE *f);
static t_stat sim_vhd_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects);
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);
@ -280,7 +280,7 @@ 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);
static void sim_os_disk_flush_raw (FILE *f);
static t_addr sim_os_disk_size_raw (FILE *f);
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);
@ -346,17 +346,18 @@ return SCPE_OK;
t_stat sim_disk_set_capac (UNIT *uptr, int32 val, char *cptr, void *desc)
{
t_addr cap;
t_offset cap;
t_stat r;
DEVICE *dptr = find_dev_from_unit (uptr);
if ((cptr == NULL) || (*cptr == 0))
return SCPE_ARG;
if (uptr->flags & UNIT_ATT)
return SCPE_ALATT;
cap = (t_addr) get_uint (cptr, 10, sim_taddr_64? 2000000: 2000, &r);
cap = (t_offset) get_uint (cptr, 10, sim_taddr_64? 2000000: 2000, &r);
if (r != SCPE_OK)
return SCPE_ARG;
uptr->capac = cap * ((t_addr) 1000000);
uptr->capac = (t_addr)((cap * ((t_offset) 1000000))/((dptr->flags & DEV_SECTORS) ? 512 : 1));
return SCPE_OK;
}
@ -366,15 +367,17 @@ t_stat sim_disk_show_capac (FILE *st, UNIT *uptr, int32 val, void *desc)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
char *cap_units = "B";
DEVICE *dptr = find_dev_from_unit (uptr);
t_offset capac = ((t_offset)uptr->capac)*((dptr->flags & DEV_SECTORS) ? 512 : 1);
if (ctx->capac_factor == 2)
cap_units = "W";
if (uptr->capac) {
if (uptr->capac >= (t_addr) 1000000)
fprintf (st, "capacity=%dM%s", (uint32) (uptr->capac / ((t_addr) 1000000)), cap_units);
if (capac) {
if (capac >= (t_addr) 1000000)
fprintf (st, "capacity=%dM%s", (uint32) (capac / ((t_addr) 1000000)), cap_units);
else if (uptr->capac >= (t_addr) 1000)
fprintf (st, "capacity=%dK%s", (uint32) (uptr->capac / ((t_addr) 1000)), cap_units);
else fprintf (st, "capacity=%d%s", (uint32) uptr->capac, cap_units);
fprintf (st, "capacity=%dK%s", (uint32) (capac / ((t_addr) 1000)), cap_units);
else fprintf (st, "capacity=%d%s", (uint32) capac, cap_units);
}
else fprintf (st, "undefined capacity");
return SCPE_OK;
@ -418,7 +421,7 @@ return (uptr->flags & DKUF_WRP)? TRUE: FALSE;
/* Get Disk size */
t_addr sim_disk_size (UNIT *uptr)
t_offset sim_disk_size (UNIT *uptr)
{
switch (DK_GET_FMT (uptr)) { /* case on format */
case DKUF_F_STD: /* SIMH format */
@ -430,7 +433,7 @@ switch (DK_GET_FMT (uptr)) { /* case on format */
return sim_os_disk_size_raw (uptr->fileref);
break;
default:
return (t_addr)-1;
return (t_offset)-1;
}
}
@ -504,18 +507,18 @@ return SCPE_OK;
static t_stat _sim_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects)
{
t_addr da;
t_offset da;
uint32 err, tbc;
size_t i;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_sim_disk_rdsect(unit=%d, lba=0x%X, sects=%d)\n", (int)(uptr-ctx->dptr->units), lba, sects);
da = ((t_addr)lba) * ctx->sector_size;
da = ((t_offset)lba) * ctx->sector_size;
tbc = sects * ctx->sector_size;
if (sectsread)
*sectsread = 0;
err = sim_fseek (uptr->fileref, da, SEEK_SET); /* set pos */
err = sim_fseeko (uptr->fileref, da, SEEK_SET); /* set pos */
if (!err) {
i = sim_fread (buf, ctx->xfer_element_size, tbc/ctx->xfer_element_size, uptr->fileref);
if (i < tbc/ctx->xfer_element_size) /* fill */
@ -620,18 +623,18 @@ return r;
static t_stat _sim_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects)
{
t_addr da;
t_offset da;
uint32 err, tbc;
size_t i;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_sim_disk_wrsect(unit=%d, lba=0x%X, sects=%d)\n", (int)(uptr-ctx->dptr->units), lba, sects);
da = ((t_addr)lba) * ctx->sector_size;
da = ((t_offset)lba) * ctx->sector_size;
tbc = sects * ctx->sector_size;
if (sectswritten)
*sectswritten = 0;
err = sim_fseek (uptr->fileref, da, SEEK_SET); /* set pos */
err = sim_fseeko (uptr->fileref, da, SEEK_SET); /* set pos */
if (!err) {
i = sim_fwrite (buf, ctx->xfer_element_size, tbc/ctx->xfer_element_size, uptr->fileref);
err = ferror (uptr->fileref);
@ -815,12 +818,12 @@ t_stat sim_disk_attach (UNIT *uptr, char *cptr, size_t sector_size, size_t xfer_
struct disk_context *ctx;
DEVICE *dptr;
FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen;
FILE *(*create_function)(const char *filename, t_addr desiredsize) = NULL;
t_addr (*size_function)(FILE *file);
FILE *(*create_function)(const char *filename, t_offset desiredsize) = NULL;
t_offset (*size_function)(FILE *file);
t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable) = NULL;
t_bool created = FALSE;
t_bool auto_format = FALSE;
t_addr capac;
t_offset capac;
if (uptr->flags & UNIT_DIS) /* disabled? */
return SCPE_UDIS;
@ -875,7 +878,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
if (!sim_quiet)
printf ("%s%d: creating new virtual disk '%s'\n", sim_dname (dptr), (int)(uptr-dptr->units), gbuf);
capac_factor = ((dptr->dwidth / dptr->aincr) == 16) ? 2 : 1; /* capacity units (word: 2, byte: 1) */
vhd = sim_vhd_disk_create (gbuf, uptr->capac*capac_factor);
vhd = sim_vhd_disk_create (gbuf, ((t_offset)uptr->capac)*capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1));
if (!vhd) {
if (!sim_quiet)
printf ("%s%d: can't create virtual disk '%s'\n", sim_dname (dptr), (int)(uptr-dptr->units), gbuf);
@ -885,7 +888,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
uint8 *copy_buf = (uint8*) malloc (1024*1024);
t_lba lba;
t_seccnt sectors_per_buffer = (t_seccnt)((1024*1024)/sector_size);
t_lba total_sectors = (t_lba)((uptr->capac*capac_factor)/sector_size);
t_lba total_sectors = (t_lba)((uptr->capac*capac_factor)/(sector_size/((dptr->flags & DEV_SECTORS) ? 512 : 1)));
t_seccnt sects = sectors_per_buffer;
if (!copy_buf) {
@ -912,7 +915,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
}
if (!sim_quiet) {
if (r == SCPE_OK)
printf ("\n%s%d: Copied %dMB. Done.\n", sim_dname (dptr), (int)(uptr-dptr->units), (int)(((t_addr)lba*sector_size)/1000000));
printf ("\n%s%d: Copied %dMB. Done.\n", sim_dname (dptr), (int)(uptr-dptr->units), (int)(((t_offset)lba*sector_size)/1000000));
else
printf ("\n%s%d: Error copying: %s.\n", sim_dname (dptr), (int)(uptr-dptr->units), sim_error_text (r));
}
@ -1013,7 +1016,7 @@ else { /* normal */
if (sim_switches & SWMASK ('E')) /* must exist? */
return _err_return (uptr, SCPE_OPENERR); /* yes, error */
if (create_function)
uptr->fileref = create_function (cptr, uptr->capac*ctx->capac_factor);/* create new file */
uptr->fileref = create_function (cptr, ((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1));/* create new file */
else
uptr->fileref = open_function (cptr, "wb+");/* open new file */
if (uptr->fileref == NULL) /* open fail? */
@ -1059,7 +1062,7 @@ if (created) {
if (secbuf == NULL)
r = SCPE_MEM;
if (r == SCPE_OK)
r = sim_disk_wrsect (uptr, (t_lba)(((uptr->capac*ctx->capac_factor) - ctx->sector_size)/ctx->sector_size), secbuf, NULL, 1); /* Write Last Sector */
r = sim_disk_wrsect (uptr, (t_lba)(((((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)) - ctx->sector_size)/ctx->sector_size), secbuf, NULL, 1); /* Write Last Sector */
if (r == SCPE_OK)
r = sim_disk_wrsect (uptr, (t_lba)(0), secbuf, NULL, 1); /* Write First Sector */
free (secbuf);
@ -1073,21 +1076,21 @@ if (created) {
}
capac = size_function (uptr->fileref);
if (capac && (capac != (t_addr)-1)) {
if (capac && (capac != (t_offset)-1)) {
if (dontautosize) {
if ((capac < (uptr->capac*ctx->capac_factor)) && (DKUF_F_STD != DK_GET_FMT (uptr))) {
if ((capac < (((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1))) && (DKUF_F_STD != DK_GET_FMT (uptr))) {
if (!sim_quiet) {
printf ("%s%d: non expandable disk %s is smaller than simulated device (", sim_dname (dptr), (int)(uptr-dptr->units), cptr);
fprint_val (stdout, capac/ctx->capac_factor, 10, T_ADDR_W, PV_LEFT);
fprint_val (stdout, (t_addr)(capac/ctx->capac_factor), 10, T_ADDR_W, PV_LEFT);
printf ("%s < ", (ctx->capac_factor == 2) ? "W" : "");
fprint_val (stdout, uptr->capac, 10, T_ADDR_W, PV_LEFT);
fprint_val (stdout, uptr->capac*((dptr->flags & DEV_SECTORS) ? 512 : 1), 10, T_ADDR_W, PV_LEFT);
printf ("%s)\n", (ctx->capac_factor == 2) ? "W" : "");
}
}
}
else
if ((capac > (uptr->capac*ctx->capac_factor)) || (DKUF_F_STD != DK_GET_FMT (uptr)))
uptr->capac = capac/ctx->capac_factor;
if ((capac > (((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1))) || (DKUF_F_STD != DK_GET_FMT (uptr)))
uptr->capac = (t_addr)(capac/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)));
}
#if defined (SIM_ASYNCH_IO)
@ -1343,11 +1346,14 @@ int32 i;
t_addr da;
int32 wds = ctx->sector_size/sizeof (uint16);
uint16 *buf;
DEVICE *dptr;
if ((sec < 2) || (wds < 16))
return SCPE_ARG;
if ((uptr->flags & UNIT_ATT) == 0)
return SCPE_UNATT;
if ((dptr = find_dev_from_unit (uptr)) == NULL)
return SCPE_NOATT;
if (uptr->flags & UNIT_RO)
return SCPE_RO;
if (ctx->capac_factor != 2) /* Must be Word oriented Capacity */
@ -1360,7 +1366,7 @@ buf[0] = buf[1] = 012345u;
buf[2] = buf[3] = 0;
for (i = 4; i < wds; i++)
buf[i] = 0177777u;
da = uptr->capac - (sec * wds);
da = (uptr->capac*((dptr->flags & DEV_SECTORS) ? 512 : 1)) - (sec * wds);
for (i = 0; (i < sec) && (i < 10); i++, da += wds)
if (sim_disk_wrsect (uptr, (t_lba)(da/wds), (void *)buf, NULL, 1)) {
free (buf);
@ -1586,7 +1592,7 @@ return "Unknown";
static t_stat sim_os_disk_implemented_raw (void)
{
return sim_taddr_64 ? SCPE_OK : SCPE_NOFNC;
return sim_toffset_64 ? SCPE_OK : SCPE_NOFNC;
}
static FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmode)
@ -1620,14 +1626,14 @@ static void sim_os_disk_flush_raw (FILE *f)
FlushFileBuffers ((HANDLE)f);
}
static t_addr sim_os_disk_size_raw (FILE *Disk)
static t_offset sim_os_disk_size_raw (FILE *Disk)
{
DWORD IoctlReturnSize;
LARGE_INTEGER Size;
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
if (GetFileSizeEx((HANDLE)Disk, &Size))
return (t_addr)(Size.QuadPart);
return (t_offset)(Size.QuadPart);
#ifdef IOCTL_STORAGE_READ_CAPACITY
if (1) {
STORAGE_READ_CAPACITY S;
@ -1642,7 +1648,7 @@ if (1) {
(DWORD) sizeof(S), /* size of output buffer */
(LPDWORD) &IoctlReturnSize, /* number of bytes returned */
(LPOVERLAPPED) NULL)) /* OVERLAPPED structure */
return (t_addr)(S.DiskLength.QuadPart);
return (t_offset)(S.DiskLength.QuadPart);
}
#endif
#ifdef IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
@ -1658,7 +1664,7 @@ if (1) {
(DWORD) sizeof(G), /* size of output buffer */
(LPDWORD) &IoctlReturnSize, /* number of bytes returned */
(LPOVERLAPPED) NULL)) /* OVERLAPPED structure */
return (t_addr)(G.DiskSize.QuadPart);
return (t_offset)(G.DiskSize.QuadPart);
}
#endif
#ifdef IOCTL_DISK_GET_DRIVE_GEOMETRY
@ -1673,11 +1679,11 @@ if (1) {
(DWORD) sizeof(G), /* size of output buffer */
(LPDWORD) &IoctlReturnSize, /* number of bytes returned */
(LPOVERLAPPED) NULL)) /* OVERLAPPED structure */
return (t_addr)(G.Cylinders.QuadPart*G.TracksPerCylinder*G.SectorsPerTrack*G.BytesPerSector);
return (t_offset)(G.Cylinders.QuadPart*G.TracksPerCylinder*G.SectorsPerTrack*G.BytesPerSector);
}
#endif
_set_errno_from_status (GetLastError ());
return (t_addr)-1;
return (t_offset)-1;
}
static t_stat sim_os_disk_unload_raw (FILE *Disk)
@ -1874,7 +1880,7 @@ return SCPE_IOERR;
static t_stat sim_os_disk_implemented_raw (void)
{
return sim_taddr_64 ? SCPE_OK : SCPE_NOFNC;
return sim_toffset_64 ? SCPE_OK : SCPE_NOFNC;
}
static FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmode)
@ -1905,13 +1911,13 @@ static void sim_os_disk_flush_raw (FILE *f)
fsync ((int)((long)f));
}
static t_addr sim_os_disk_size_raw (FILE *f)
static t_offset sim_os_disk_size_raw (FILE *f)
{
struct stat64 statb;
if (fstat64 ((int)((long)f), &statb))
return (t_addr)-1;
return (t_addr)statb.st_size;
return (t_offset)-1;
return (t_offset)statb.st_size;
}
static t_stat sim_os_disk_unload_raw (FILE *f)
@ -1997,9 +2003,9 @@ static void sim_os_disk_flush_raw (FILE *f)
{
}
static t_addr sim_os_disk_size_raw (FILE *f)
static t_offset sim_os_disk_size_raw (FILE *f)
{
return (t_addr)-1;
return (t_offset)-1;
}
static t_stat sim_os_disk_unload_raw (FILE *f)
@ -2057,7 +2063,7 @@ static FILE *sim_vhd_disk_merge (const char *szVHDPath, char **ParentVHD)
return NULL;
}
static FILE *sim_vhd_disk_create (const char *szVHDPath, t_addr desiredsize)
static FILE *sim_vhd_disk_create (const char *szVHDPath, t_offset desiredsize)
{
return NULL;
}
@ -2076,9 +2082,9 @@ static void sim_vhd_disk_flush (FILE *f)
{
}
static t_addr sim_vhd_disk_size (FILE *f)
static t_offset sim_vhd_disk_size (FILE *f)
{
return (t_addr)-1;
return (t_offset)-1;
}
static t_stat sim_vhd_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects)
@ -2419,7 +2425,7 @@ typedef struct VHD_IOData *VHDHANDLE;
static t_stat ReadFilePosition(FILE *File, void *buf, size_t bufsize, size_t *bytesread, uint64 position)
{
uint32 err = sim_fseek (File, (t_addr)position, SEEK_SET);
uint32 err = sim_fseeko (File, (t_offset)position, SEEK_SET);
size_t i;
if (bytesread)
@ -2435,7 +2441,7 @@ return (err ? SCPE_IOERR : SCPE_OK);
static t_stat WriteFilePosition(FILE *File, void *buf, size_t bufsize, size_t *byteswritten, uint64 position)
{
uint32 err = sim_fseek (File, (t_addr)position, SEEK_SET);
uint32 err = sim_fseeko (File, (t_offset)position, SEEK_SET);
size_t i;
if (byteswritten)
@ -2990,11 +2996,11 @@ if ((NULL != hVHD) && (hVHD->File))
fflush (hVHD->File);
}
static t_addr sim_vhd_disk_size (FILE *f)
static t_offset sim_vhd_disk_size (FILE *f)
{
VHDHANDLE hVHD = (VHDHANDLE)f;
return (t_addr)(NtoHll (hVHD->Footer.CurrentSize));
return (t_offset)(NtoHll (hVHD->Footer.CurrentSize));
}
#include <stdlib.h>
@ -3506,7 +3512,7 @@ errno = Status;
return hVHD;
}
static FILE *sim_vhd_disk_create (const char *szVHDPath, t_addr desiredsize)
static FILE *sim_vhd_disk_create (const char *szVHDPath, t_offset desiredsize)
{
return (FILE *)CreateVirtualDisk (szVHDPath, (uint32)(desiredsize/512), 0, (sim_switches & SWMASK ('X')));
}

View file

@ -85,7 +85,7 @@ t_stat sim_disk_clearerr (UNIT *uptr);
t_bool sim_disk_isavailable (UNIT *uptr);
t_bool sim_disk_isavailable_a (UNIT *uptr, DISK_PCALLBACK callback);
t_bool sim_disk_wrp (UNIT *uptr);
t_addr sim_disk_size (UNIT *uptr);
t_offset sim_disk_size (UNIT *uptr);
t_bool sim_disk_vhd_support (void);
t_bool sim_disk_raw_support (void);
void sim_disk_data_trace (UNIT *uptr, const uint8 *data, size_t lba, size_t len, const char* txt, int detail, uint32 reason);

102
sim_fio.c
View file

@ -42,11 +42,12 @@
sim_fopen - open file
sim_fread - endian independent read (formerly fxread)
sim_write - endian independent write (formerly fxwrite)
sim_fseek - extended (>32b) seek (formerly fseek_ext)
sim_fseek - conditionally extended (>32b) seek (
sim_fseeko - extended seek (>32b if available)
sim_fsize - get file size
sim_fsize_name - get file size of named file
sim_fsize_ex - get file size as a t_addr
sim_fsize_name_ex - get file size as a t_addr of named file
sim_fsize_ex - get file size as a t_offset
sim_fsize_name_ex - get file size as a t_offset of named file
sim_buf_copy_swapped - copy data swapping elements along the way
sim_buf_swap_data - swap data elements inplace in buffer
@ -57,7 +58,9 @@
#include "sim_defs.h"
int32 sim_end = 1; /* 1 = little */
t_bool sim_end; /* TRUE = little endian, FALSE = big endian */
t_bool sim_taddr_64; /* t_addr is > 32b and Large File Support available */
t_bool sim_toffset_64; /* Large File (>2GB) file I/O Support available */
/* OS-independent, endian independent binary I/O package
@ -81,7 +84,9 @@ int32 sim_finit (void)
union {int32 i; char c[sizeof (int32)]; } end_test;
end_test.i = 1; /* test endian-ness */
sim_end = end_test.c[0];
sim_end = (end_test.c[0] != 0);
sim_toffset_64 = (sizeof(t_offset) > sizeof(int32)); /* Large File (>2GB) support */
sim_taddr_64 = sim_toffset_64 && (sizeof(t_addr) > sizeof(int32));
return sim_end;
}
@ -171,27 +176,27 @@ return total;
/* Forward Declaration */
static t_addr _sim_ftell (FILE *st);
static t_offset _sim_ftell (FILE *st);
/* Get file size */
t_addr sim_fsize_ex (FILE *fp)
t_offset sim_fsize_ex (FILE *fp)
{
t_addr pos, sz;
t_offset pos, sz;
if (fp == NULL)
return 0;
pos = _sim_ftell (fp);
sim_fseek (fp, 0, SEEK_END);
sz = _sim_ftell (fp);
sim_fseek (fp, pos, SEEK_SET);
sim_fseeko (fp, pos, SEEK_SET);
return sz;
}
t_addr sim_fsize_name_ex (char *fname)
t_offset sim_fsize_name_ex (char *fname)
{
FILE *fp;
t_addr sz;
t_offset sz;
if ((fp = sim_fopen (fname, "rb")) == NULL)
return 0;
@ -219,30 +224,25 @@ FILE *sim_fopen (const char *file, const char *mode)
#if defined (VMS)
return fopen (file, mode, "ALQ=32", "DEQ=4096",
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
#elif defined (USE_INT64) && defined (USE_ADDR64) && (defined (__linux) || defined (__linux__) || defined (__hpux))
#elif defined (__linux) || defined (__linux__) || defined (__hpux)
return fopen64 (file, mode);
#else
return fopen (file, mode);
#endif
}
/* Long seek */
#if defined (USE_INT64) && defined (USE_ADDR64)
/* 64b VMS */
#if ((defined (__ALPHA) || defined (__ia64)) && defined (VMS) && (__DECC_VER >= 60590001)) || (defined(__sun__) && defined(_LARGEFILE_SOURCE))
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr offset, int whence)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
return fseeko (st, (off_t)offset, whence);
}
static t_addr _sim_ftell (FILE *st)
static t_offset _sim_ftell (FILE *st)
{
return (t_addr)(ftello (st));
return (t_offset)(ftello (st));
}
#endif
@ -250,16 +250,15 @@ return (t_addr)(ftello (st));
/* Alpha UNIX - natively 64b */
#if defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr offset, int whence)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
return fseek (st, offset, whence);
}
static t_addr _sim_ftell (FILE *st)
static t_offset _sim_ftell (FILE *st)
{
return (t_addr)(ftell (st));
return (t_offset)(ftell (st));
}
#endif
@ -267,10 +266,10 @@ return (t_addr)(ftell (st));
/* Windows */
#if defined (_WIN32)
#define S_SIM_IO_FSEEK_EXT_ 1
#define S_SIM_IO_FSEEK_EXT_ 1
#include <sys/stat.h>
int sim_fseek (FILE *st, t_addr offset, int whence)
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
fpos_t fileaddr;
struct _stati64 statb;
@ -278,7 +277,7 @@ struct _stati64 statb;
switch (whence) {
case SEEK_SET:
fileaddr = offset;
fileaddr = (fpos_t)offset;
break;
case SEEK_END:
@ -300,12 +299,12 @@ switch (whence) {
return fsetpos (st, &fileaddr);
}
static t_addr _sim_ftell (FILE *st)
static t_offset _sim_ftell (FILE *st)
{
fpos_t fileaddr;
if (fgetpos (st, &fileaddr))
return (-1);
return (t_addr)fileaddr;
return (t_offset)fileaddr;
}
#endif /* end Windows */
@ -313,16 +312,15 @@ return (t_addr)fileaddr;
/* Linux */
#if defined (__linux) || defined (__linux__) || defined (__hpux)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr xpos, int origin)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset xpos, int origin)
{
return fseeko64 (st, xpos, origin);
return fseeko64 (st, (off64_t)xpos, origin);
}
static t_addr _sim_ftell (FILE *st)
static t_offset _sim_ftell (FILE *st)
{
return (t_addr)(ftello64 (st));
return (t_offset)(ftello64 (st));
}
#endif /* end Linux with LFS */
@ -330,38 +328,34 @@ return (t_addr)(ftello64 (st));
/* Apple OS/X */
#if defined (__APPLE__) || defined (__FreeBSD__)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr xpos, int origin)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_offset xpos, int origin)
{
return fseeko (st, xpos, origin);
return fseeko (st, (off_t)xpos, origin);
}
static t_addr _sim_ftell (FILE *st)
static t_offset _sim_ftell (FILE *st)
{
return (t_addr)(ftello (st));
return (t_offset)(ftello (st));
}
#endif /* end Apple OS/X */
#endif /* end 64b seek defs */
/* Default: no OS-specific routine has been defined */
#if !defined (S_SIM_IO_FSEEK_EXT_)
#define S_SIM_IO_FSEEK_EXT_ 0
int sim_fseek (FILE *st, t_addr xpos, int origin)
int sim_fseeko (FILE *st, t_offset xpos, int origin)
{
return fseek (st, (int32) xpos, origin);
return fseek (st, (long) xpos, origin);
}
static t_addr _sim_ftell (FILE *st)
static t_offset _sim_ftell (FILE *st)
{
return (t_addr)(ftell (st));
return (t_offset)(ftell (st));
}
#endif
uint32 sim_taddr_64 = S_SIM_IO_FSEEK_EXT_;
int sim_fseek (FILE *st, t_addr offset, int whence)
{
return sim_fseeko (st, (t_offset)offset, whence);
}

View file

@ -38,18 +38,28 @@
#define fxwrite(a,b,c,d) sim_fwrite (a, b, c, d)
int32 sim_finit (void);
#if defined (__linux) || defined (__linux__) || defined (__hpux) || \
(defined (VMS) && (defined (__ALPHA) || defined (__ia64)) && (__DECC_VER >= 60590001)) || \
(defined(__sun__) && defined(_LARGEFILE_SOURCE)) || \
defined (_WIN32) || defined (__APPLE__) || defined (__FreeBSD__)
typedef t_int64 t_offset;
#else
typedef int32 t_offset;
#endif
FILE *sim_fopen (const char *file, const char *mode);
int sim_fseek (FILE *st, t_addr offset, int whence);
int sim_fseeko (FILE *st, t_offset offset, int whence);
size_t sim_fread (void *bptr, size_t size, size_t count, FILE *fptr);
size_t sim_fwrite (void *bptr, size_t size, size_t count, FILE *fptr);
uint32 sim_fsize (FILE *fptr);
uint32 sim_fsize_name (char *fname);
t_addr sim_fsize_ex (FILE *fptr);
t_addr sim_fsize_name_ex (char *fname);
t_offset sim_fsize_ex (FILE *fptr);
t_offset sim_fsize_name_ex (char *fname);
void sim_buf_swap_data (void *bptr, size_t size, size_t count);
void sim_buf_copy_swapped (void *dptr, void *bptr, size_t size, size_t count);
extern uint32 sim_taddr_64;
extern int32 sim_end;
extern t_bool sim_taddr_64; /* t_addr is > 32b and Large File Support available */
extern t_bool sim_toffset_64; /* Large File (>2GB) file I/O support */
extern t_bool sim_end; /* TRUE = little endian, FALSE = big endian */
#endif

View file

@ -389,7 +389,7 @@ int32 fdcdrv(int32 io, int32 data)
pos = 0x200; /* Read in SIR */
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcdrv: Read pos = %ld ($%04X)", pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, 0); /* seek to offset */
sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */
sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */
@ -435,7 +435,7 @@ int32 fdccmd(int32 io, int32 data)
pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdccmd: Read pos = %ld ($%08X)", pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, 0); /* seek to offset */
sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */
sim_fread(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* read in buffer */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */
@ -451,7 +451,7 @@ int32 fdccmd(int32 io, int32 data)
pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdccmd: Write pos = %ld ($%08X)", pos, (unsigned int) pos);
sim_fseek(dsk_unit[cur_dsk].fileref, pos, 0); /* seek to offset */
sim_fseek(dsk_unit[cur_dsk].fileref, pos, SEEK_SET); /* seek to offset */
wrt_flag = 1; /* set write flag */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ;/* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */