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)); 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); sectRecordType = fgetc(myDisk->file);
switch(sectRecordType) { switch(sectRecordType) {
@ -642,7 +642,7 @@ t_stat sectWrite(DISK_INFO *myDisk,
sectorFileOffset = myDisk->track[Cyl][Head].sectorOffsetMap[Sector-start_sect]; 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) { if (*flags & IMD_DISK_IO_ERROR_GENERAL) {
sectRecordType = SECT_RECORD_UNAVAILABLE; sectRecordType = SECT_RECORD_UNAVAILABLE;

View file

@ -654,7 +654,7 @@ struct drvtyp {
d##_GPC, d##_XBN, d##_DBN, d##_LBN, \ d##_GPC, d##_XBN, d##_DBN, d##_LBN, \
d##_RCTS, d##_RCTC, d##_RBN, d##_MOD, \ d##_RCTS, d##_RCTC, d##_RBN, d##_MOD, \
d##_MED, d##_FLGS d##_MED, d##_FLGS
#define RQ_SIZE(d) (d##_LBN * RQ_NUMBY) #define RQ_SIZE(d) d##_LBN
static struct drvtyp drv_tab[] = { static struct drvtyp drv_tab[] = {
{ RQ_DRV (RX50), "RX50" }, { RQ_DRV (RX50), "RX50" },
@ -1011,7 +1011,7 @@ DEVICE rq_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &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, 0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description &rq_description
}; };
@ -1086,7 +1086,7 @@ DEVICE rqb_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &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, 0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description &rq_description
}; };
@ -1161,7 +1161,7 @@ DEVICE rqc_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &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, 0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description &rq_description
}; };
@ -1236,7 +1236,7 @@ DEVICE rqd_dev = {
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16, RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
NULL, NULL, &rq_reset, NULL, NULL, &rq_reset,
&rq_boot, &rq_attach, &rq_detach, &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, 0, rq_debug, NULL, NULL, &rq_help, NULL, NULL,
&rq_description &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 dtyp = GET_DTYPE (uptr->flags); /* get drive type */
uint32 lbn = GETP32 (pkt, RW_LBNL); /* get lbn */ uint32 lbn = GETP32 (pkt, RW_LBNL); /* get lbn */
uint32 bc = GETP32 (pkt, RW_BCL); /* get byte cnt */ 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? */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
return (ST_OFL | SB_OFL_NV); /* offl no vol */ 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) 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 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"); sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_putr_unit\n");
@ -2723,7 +2723,7 @@ if (cptr) {
drv_tab[val].lbn = cap; drv_tab[val].lbn = cap;
} }
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (val << UNIT_V_DTYPE); 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; return SCPE_OK;
} }

View file

@ -20,6 +20,7 @@
RQ has new disk types: RC25, RCF25, RA80 RQ has new disk types: RC25, RCF25, RA80
RQ device has a settable controller type (RQDX3, UDA50, KLESI, RUX50) RQ device has a settable controller type (RQDX3, UDA50, KLESI, RUX50)
RQ disks default to Autosize without regard to disk type 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. 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 DZ on Unibus systems can have up to 256 ports (default of 32), on
Qbus systems 128 port limit (default of 16). 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; t_addr psize = uptr->capac;
char scale, width; char scale, width;
if (dptr->flags & DEV_SECTORS) {
kval = kval / 512;
mval = mval / 512;
}
if ((dptr->dwidth / dptr->aincr) > 8) if ((dptr->dwidth / dptr->aincr) > 8)
width = 'W'; width = 'W';
else width = 'B'; else width = 'B';
@ -2753,7 +2757,6 @@ if (flag) {
fprintf (st, "\n\t\t%s", sim_snet); fprintf (st, "\n\t\t%s", sim_snet);
idle_capable = sim_timer_idle_capable (&os_tick_size); 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\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()) if (sim_disk_vhd_support())
fprintf (st, "\n\t\tVirtual Hard Disk (VHD) support"); fprintf (st, "\n\t\tVirtual Hard Disk (VHD) support");
if (sim_disk_raw_support()) if (sim_disk_raw_support())
@ -2770,6 +2773,7 @@ if (flag) {
fprintf (st, "\n\tHost Platform:"); fprintf (st, "\n\tHost Platform:");
fprintf (st, "\n\t\tMemory Access: %s Endian", sim_end ? "Little" : "Big"); 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\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) #if defined(__VMS)
fprintf (st, "\n\t\tOS: VMS"); fprintf (st, "\n\t\tOS: VMS");
#elif defined(_WIN32) #elif defined(_WIN32)

View file

@ -358,6 +358,7 @@ struct sim_device {
#define DEV_V_DEBUG 3 /* debug capability */ #define DEV_V_DEBUG 3 /* debug capability */
#define DEV_V_TYPE 4 /* Attach type */ #define DEV_V_TYPE 4 /* Attach type */
#define DEV_S_TYPE 3 /* Width of Type Field */ #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_31 12 /* user flags, V3.1 */
#define DEV_V_UF 16 /* user flags */ #define DEV_V_UF 16 /* user flags */
#define DEV_V_RSV 31 /* reserved */ #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_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_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_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 */ #define DEV_NET 0 /* Deprecated - meaningless */

View file

@ -265,12 +265,12 @@ if (ctx) {
static t_stat sim_vhd_disk_implemented (void); 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_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_create_diff (const char *szVHDPath, const char *szParentVHDPath);
static FILE *sim_vhd_disk_merge (const char *szVHDPath, char **ParentVHD); static FILE *sim_vhd_disk_merge (const char *szVHDPath, char **ParentVHD);
static int sim_vhd_disk_close (FILE *f); static int sim_vhd_disk_close (FILE *f);
static void sim_vhd_disk_flush (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_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_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_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 FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmode);
static int sim_os_disk_close_raw (FILE *f); static int sim_os_disk_close_raw (FILE *f);
static void sim_os_disk_flush_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_stat sim_os_disk_unload_raw (FILE *f);
static t_bool sim_os_disk_isavailable_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_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_stat sim_disk_set_capac (UNIT *uptr, int32 val, char *cptr, void *desc)
{ {
t_addr cap; t_offset cap;
t_stat r; t_stat r;
DEVICE *dptr = find_dev_from_unit (uptr);
if ((cptr == NULL) || (*cptr == 0)) if ((cptr == NULL) || (*cptr == 0))
return SCPE_ARG; return SCPE_ARG;
if (uptr->flags & UNIT_ATT) if (uptr->flags & UNIT_ATT)
return SCPE_ALATT; 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) if (r != SCPE_OK)
return SCPE_ARG; 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; 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; struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
char *cap_units = "B"; 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) if (ctx->capac_factor == 2)
cap_units = "W"; cap_units = "W";
if (uptr->capac) { if (capac) {
if (uptr->capac >= (t_addr) 1000000) if (capac >= (t_addr) 1000000)
fprintf (st, "capacity=%dM%s", (uint32) (uptr->capac / ((t_addr) 1000000)), cap_units); fprintf (st, "capacity=%dM%s", (uint32) (capac / ((t_addr) 1000000)), cap_units);
else if (uptr->capac >= (t_addr) 1000) else if (uptr->capac >= (t_addr) 1000)
fprintf (st, "capacity=%dK%s", (uint32) (uptr->capac / ((t_addr) 1000)), cap_units); fprintf (st, "capacity=%dK%s", (uint32) (capac / ((t_addr) 1000)), cap_units);
else fprintf (st, "capacity=%d%s", (uint32) uptr->capac, cap_units); else fprintf (st, "capacity=%d%s", (uint32) capac, cap_units);
} }
else fprintf (st, "undefined capacity"); else fprintf (st, "undefined capacity");
return SCPE_OK; return SCPE_OK;
@ -418,7 +421,7 @@ return (uptr->flags & DKUF_WRP)? TRUE: FALSE;
/* Get Disk size */ /* 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 */ switch (DK_GET_FMT (uptr)) { /* case on format */
case DKUF_F_STD: /* SIMH 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); return sim_os_disk_size_raw (uptr->fileref);
break; break;
default: 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) 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; uint32 err, tbc;
size_t i; size_t i;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; 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); 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; tbc = sects * ctx->sector_size;
if (sectsread) if (sectsread)
*sectsread = 0; *sectsread = 0;
err = sim_fseek (uptr->fileref, da, SEEK_SET); /* set pos */ err = sim_fseeko (uptr->fileref, da, SEEK_SET); /* set pos */
if (!err) { if (!err) {
i = sim_fread (buf, ctx->xfer_element_size, tbc/ctx->xfer_element_size, uptr->fileref); i = sim_fread (buf, ctx->xfer_element_size, tbc/ctx->xfer_element_size, uptr->fileref);
if (i < tbc/ctx->xfer_element_size) /* fill */ 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) 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; uint32 err, tbc;
size_t i; size_t i;
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; 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); 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; tbc = sects * ctx->sector_size;
if (sectswritten) if (sectswritten)
*sectswritten = 0; *sectswritten = 0;
err = sim_fseek (uptr->fileref, da, SEEK_SET); /* set pos */ err = sim_fseeko (uptr->fileref, da, SEEK_SET); /* set pos */
if (!err) { if (!err) {
i = sim_fwrite (buf, ctx->xfer_element_size, tbc/ctx->xfer_element_size, uptr->fileref); i = sim_fwrite (buf, ctx->xfer_element_size, tbc/ctx->xfer_element_size, uptr->fileref);
err = ferror (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; struct disk_context *ctx;
DEVICE *dptr; DEVICE *dptr;
FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen; FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen;
FILE *(*create_function)(const char *filename, t_addr desiredsize) = NULL; FILE *(*create_function)(const char *filename, t_offset desiredsize) = NULL;
t_addr (*size_function)(FILE *file); t_offset (*size_function)(FILE *file);
t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable) = NULL; t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable) = NULL;
t_bool created = FALSE; t_bool created = FALSE;
t_bool auto_format = FALSE; t_bool auto_format = FALSE;
t_addr capac; t_offset capac;
if (uptr->flags & UNIT_DIS) /* disabled? */ if (uptr->flags & UNIT_DIS) /* disabled? */
return SCPE_UDIS; return SCPE_UDIS;
@ -875,7 +878,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
if (!sim_quiet) if (!sim_quiet)
printf ("%s%d: creating new virtual disk '%s'\n", sim_dname (dptr), (int)(uptr-dptr->units), gbuf); 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) */ 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 (!vhd) {
if (!sim_quiet) if (!sim_quiet)
printf ("%s%d: can't create virtual disk '%s'\n", sim_dname (dptr), (int)(uptr-dptr->units), gbuf); 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); uint8 *copy_buf = (uint8*) malloc (1024*1024);
t_lba lba; t_lba lba;
t_seccnt sectors_per_buffer = (t_seccnt)((1024*1024)/sector_size); 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; t_seccnt sects = sectors_per_buffer;
if (!copy_buf) { if (!copy_buf) {
@ -912,7 +915,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
} }
if (!sim_quiet) { if (!sim_quiet) {
if (r == SCPE_OK) 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 else
printf ("\n%s%d: Error copying: %s.\n", sim_dname (dptr), (int)(uptr-dptr->units), sim_error_text (r)); 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? */ if (sim_switches & SWMASK ('E')) /* must exist? */
return _err_return (uptr, SCPE_OPENERR); /* yes, error */ return _err_return (uptr, SCPE_OPENERR); /* yes, error */
if (create_function) 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 else
uptr->fileref = open_function (cptr, "wb+");/* open new file */ uptr->fileref = open_function (cptr, "wb+");/* open new file */
if (uptr->fileref == NULL) /* open fail? */ if (uptr->fileref == NULL) /* open fail? */
@ -1059,7 +1062,7 @@ if (created) {
if (secbuf == NULL) if (secbuf == NULL)
r = SCPE_MEM; r = SCPE_MEM;
if (r == SCPE_OK) 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) if (r == SCPE_OK)
r = sim_disk_wrsect (uptr, (t_lba)(0), secbuf, NULL, 1); /* Write First Sector */ r = sim_disk_wrsect (uptr, (t_lba)(0), secbuf, NULL, 1); /* Write First Sector */
free (secbuf); free (secbuf);
@ -1073,21 +1076,21 @@ if (created) {
} }
capac = size_function (uptr->fileref); capac = size_function (uptr->fileref);
if (capac && (capac != (t_addr)-1)) { if (capac && (capac != (t_offset)-1)) {
if (dontautosize) { 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) { if (!sim_quiet) {
printf ("%s%d: non expandable disk %s is smaller than simulated device (", sim_dname (dptr), (int)(uptr-dptr->units), cptr); 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" : ""); 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" : ""); printf ("%s)\n", (ctx->capac_factor == 2) ? "W" : "");
} }
} }
} }
else else
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)))
uptr->capac = capac/ctx->capac_factor; uptr->capac = (t_addr)(capac/(ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)));
} }
#if defined (SIM_ASYNCH_IO) #if defined (SIM_ASYNCH_IO)
@ -1343,11 +1346,14 @@ int32 i;
t_addr da; t_addr da;
int32 wds = ctx->sector_size/sizeof (uint16); int32 wds = ctx->sector_size/sizeof (uint16);
uint16 *buf; uint16 *buf;
DEVICE *dptr;
if ((sec < 2) || (wds < 16)) if ((sec < 2) || (wds < 16))
return SCPE_ARG; return SCPE_ARG;
if ((uptr->flags & UNIT_ATT) == 0) if ((uptr->flags & UNIT_ATT) == 0)
return SCPE_UNATT; return SCPE_UNATT;
if ((dptr = find_dev_from_unit (uptr)) == NULL)
return SCPE_NOATT;
if (uptr->flags & UNIT_RO) if (uptr->flags & UNIT_RO)
return SCPE_RO; return SCPE_RO;
if (ctx->capac_factor != 2) /* Must be Word oriented Capacity */ if (ctx->capac_factor != 2) /* Must be Word oriented Capacity */
@ -1360,7 +1366,7 @@ buf[0] = buf[1] = 012345u;
buf[2] = buf[3] = 0; buf[2] = buf[3] = 0;
for (i = 4; i < wds; i++) for (i = 4; i < wds; i++)
buf[i] = 0177777u; 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) for (i = 0; (i < sec) && (i < 10); i++, da += wds)
if (sim_disk_wrsect (uptr, (t_lba)(da/wds), (void *)buf, NULL, 1)) { if (sim_disk_wrsect (uptr, (t_lba)(da/wds), (void *)buf, NULL, 1)) {
free (buf); free (buf);
@ -1586,7 +1592,7 @@ return "Unknown";
static t_stat sim_os_disk_implemented_raw (void) 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) 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); 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; DWORD IoctlReturnSize;
LARGE_INTEGER Size; LARGE_INTEGER Size;
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize); WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize);
if (GetFileSizeEx((HANDLE)Disk, &Size)) if (GetFileSizeEx((HANDLE)Disk, &Size))
return (t_addr)(Size.QuadPart); return (t_offset)(Size.QuadPart);
#ifdef IOCTL_STORAGE_READ_CAPACITY #ifdef IOCTL_STORAGE_READ_CAPACITY
if (1) { if (1) {
STORAGE_READ_CAPACITY S; STORAGE_READ_CAPACITY S;
@ -1642,7 +1648,7 @@ if (1) {
(DWORD) sizeof(S), /* size of output buffer */ (DWORD) sizeof(S), /* size of output buffer */
(LPDWORD) &IoctlReturnSize, /* number of bytes returned */ (LPDWORD) &IoctlReturnSize, /* number of bytes returned */
(LPOVERLAPPED) NULL)) /* OVERLAPPED structure */ (LPOVERLAPPED) NULL)) /* OVERLAPPED structure */
return (t_addr)(S.DiskLength.QuadPart); return (t_offset)(S.DiskLength.QuadPart);
} }
#endif #endif
#ifdef IOCTL_DISK_GET_DRIVE_GEOMETRY_EX #ifdef IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
@ -1658,7 +1664,7 @@ if (1) {
(DWORD) sizeof(G), /* size of output buffer */ (DWORD) sizeof(G), /* size of output buffer */
(LPDWORD) &IoctlReturnSize, /* number of bytes returned */ (LPDWORD) &IoctlReturnSize, /* number of bytes returned */
(LPOVERLAPPED) NULL)) /* OVERLAPPED structure */ (LPOVERLAPPED) NULL)) /* OVERLAPPED structure */
return (t_addr)(G.DiskSize.QuadPart); return (t_offset)(G.DiskSize.QuadPart);
} }
#endif #endif
#ifdef IOCTL_DISK_GET_DRIVE_GEOMETRY #ifdef IOCTL_DISK_GET_DRIVE_GEOMETRY
@ -1673,11 +1679,11 @@ if (1) {
(DWORD) sizeof(G), /* size of output buffer */ (DWORD) sizeof(G), /* size of output buffer */
(LPDWORD) &IoctlReturnSize, /* number of bytes returned */ (LPDWORD) &IoctlReturnSize, /* number of bytes returned */
(LPOVERLAPPED) NULL)) /* OVERLAPPED structure */ (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 #endif
_set_errno_from_status (GetLastError ()); _set_errno_from_status (GetLastError ());
return (t_addr)-1; return (t_offset)-1;
} }
static t_stat sim_os_disk_unload_raw (FILE *Disk) 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) 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) 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)); 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; struct stat64 statb;
if (fstat64 ((int)((long)f), &statb)) if (fstat64 ((int)((long)f), &statb))
return (t_addr)-1; return (t_offset)-1;
return (t_addr)statb.st_size; return (t_offset)statb.st_size;
} }
static t_stat sim_os_disk_unload_raw (FILE *f) 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) 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; 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; 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) 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) 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; size_t i;
if (bytesread) 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) 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; size_t i;
if (byteswritten) if (byteswritten)
@ -2990,11 +2996,11 @@ if ((NULL != hVHD) && (hVHD->File))
fflush (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; VHDHANDLE hVHD = (VHDHANDLE)f;
return (t_addr)(NtoHll (hVHD->Footer.CurrentSize)); return (t_offset)(NtoHll (hVHD->Footer.CurrentSize));
} }
#include <stdlib.h> #include <stdlib.h>
@ -3506,7 +3512,7 @@ errno = Status;
return hVHD; 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'))); 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 (UNIT *uptr);
t_bool sim_disk_isavailable_a (UNIT *uptr, DISK_PCALLBACK callback); t_bool sim_disk_isavailable_a (UNIT *uptr, DISK_PCALLBACK callback);
t_bool sim_disk_wrp (UNIT *uptr); 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_vhd_support (void);
t_bool sim_disk_raw_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); void sim_disk_data_trace (UNIT *uptr, const uint8 *data, size_t lba, size_t len, const char* txt, int detail, uint32 reason);

View file

@ -42,11 +42,12 @@
sim_fopen - open file sim_fopen - open file
sim_fread - endian independent read (formerly fxread) sim_fread - endian independent read (formerly fxread)
sim_write - endian independent write (formerly fxwrite) 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 - get file size
sim_fsize_name - get file size of named file sim_fsize_name - get file size of named file
sim_fsize_ex - get file size as a t_addr sim_fsize_ex - get file size as a t_offset
sim_fsize_name_ex - get file size as a t_addr of named file 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_copy_swapped - copy data swapping elements along the way
sim_buf_swap_data - swap data elements inplace in buffer sim_buf_swap_data - swap data elements inplace in buffer
@ -57,7 +58,9 @@
#include "sim_defs.h" #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 /* 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; union {int32 i; char c[sizeof (int32)]; } end_test;
end_test.i = 1; /* test endian-ness */ 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; return sim_end;
} }
@ -171,27 +176,27 @@ return total;
/* Forward Declaration */ /* Forward Declaration */
static t_addr _sim_ftell (FILE *st); static t_offset _sim_ftell (FILE *st);
/* Get file size */ /* 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) if (fp == NULL)
return 0; return 0;
pos = _sim_ftell (fp); pos = _sim_ftell (fp);
sim_fseek (fp, 0, SEEK_END); sim_fseek (fp, 0, SEEK_END);
sz = _sim_ftell (fp); sz = _sim_ftell (fp);
sim_fseek (fp, pos, SEEK_SET); sim_fseeko (fp, pos, SEEK_SET);
return sz; return sz;
} }
t_addr sim_fsize_name_ex (char *fname) t_offset sim_fsize_name_ex (char *fname)
{ {
FILE *fp; FILE *fp;
t_addr sz; t_offset sz;
if ((fp = sim_fopen (fname, "rb")) == NULL) if ((fp = sim_fopen (fname, "rb")) == NULL)
return 0; return 0;
@ -219,30 +224,25 @@ FILE *sim_fopen (const char *file, const char *mode)
#if defined (VMS) #if defined (VMS)
return fopen (file, mode, "ALQ=32", "DEQ=4096", return fopen (file, mode, "ALQ=32", "DEQ=4096",
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm"); "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); return fopen64 (file, mode);
#else #else
return fopen (file, mode); return fopen (file, mode);
#endif #endif
} }
/* Long seek */
#if defined (USE_INT64) && defined (USE_ADDR64)
/* 64b VMS */ /* 64b VMS */
#if ((defined (__ALPHA) || defined (__ia64)) && defined (VMS) && (__DECC_VER >= 60590001)) || (defined(__sun__) && defined(_LARGEFILE_SOURCE)) #if ((defined (__ALPHA) || defined (__ia64)) && defined (VMS) && (__DECC_VER >= 60590001)) || (defined(__sun__) && defined(_LARGEFILE_SOURCE))
#define S_SIM_IO_FSEEK_EXT_ 1 #define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset offset, int whence)
int sim_fseek (FILE *st, t_addr offset, int whence)
{ {
return fseeko (st, (off_t)offset, 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 #endif
@ -251,15 +251,14 @@ return (t_addr)(ftello (st));
#if defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */ #if defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */
#define S_SIM_IO_FSEEK_EXT_ 1 #define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset offset, int whence)
int sim_fseek (FILE *st, t_addr offset, int whence)
{ {
return fseek (st, offset, 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 #endif
@ -270,7 +269,7 @@ return (t_addr)(ftell (st));
#define S_SIM_IO_FSEEK_EXT_ 1 #define S_SIM_IO_FSEEK_EXT_ 1
#include <sys/stat.h> #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; fpos_t fileaddr;
struct _stati64 statb; struct _stati64 statb;
@ -278,7 +277,7 @@ struct _stati64 statb;
switch (whence) { switch (whence) {
case SEEK_SET: case SEEK_SET:
fileaddr = offset; fileaddr = (fpos_t)offset;
break; break;
case SEEK_END: case SEEK_END:
@ -300,12 +299,12 @@ switch (whence) {
return fsetpos (st, &fileaddr); return fsetpos (st, &fileaddr);
} }
static t_addr _sim_ftell (FILE *st) static t_offset _sim_ftell (FILE *st)
{ {
fpos_t fileaddr; fpos_t fileaddr;
if (fgetpos (st, &fileaddr)) if (fgetpos (st, &fileaddr))
return (-1); return (-1);
return (t_addr)fileaddr; return (t_offset)fileaddr;
} }
#endif /* end Windows */ #endif /* end Windows */
@ -314,15 +313,14 @@ return (t_addr)fileaddr;
#if defined (__linux) || defined (__linux__) || defined (__hpux) #if defined (__linux) || defined (__linux__) || defined (__hpux)
#define S_SIM_IO_FSEEK_EXT_ 1 #define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseeko (FILE *st, t_offset xpos, int origin)
int sim_fseek (FILE *st, t_addr 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 */ #endif /* end Linux with LFS */
@ -331,37 +329,33 @@ return (t_addr)(ftello64 (st));
#if defined (__APPLE__) || defined (__FreeBSD__) #if defined (__APPLE__) || defined (__FreeBSD__)
#define S_SIM_IO_FSEEK_EXT_ 1 #define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_offset xpos, int origin)
int sim_fseek (FILE *st, t_addr 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 Apple OS/X */
#endif /* end 64b seek defs */
/* Default: no OS-specific routine has been defined */ /* Default: no OS-specific routine has been defined */
#if !defined (S_SIM_IO_FSEEK_EXT_) #if !defined (S_SIM_IO_FSEEK_EXT_)
#define S_SIM_IO_FSEEK_EXT_ 0 int sim_fseeko (FILE *st, t_offset xpos, int origin)
int sim_fseek (FILE *st, t_addr 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 #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) #define fxwrite(a,b,c,d) sim_fwrite (a, b, c, d)
int32 sim_finit (void); 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); FILE *sim_fopen (const char *file, const char *mode);
int sim_fseek (FILE *st, t_addr offset, int whence); 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_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); size_t sim_fwrite (void *bptr, size_t size, size_t count, FILE *fptr);
uint32 sim_fsize (FILE *fptr); uint32 sim_fsize (FILE *fptr);
uint32 sim_fsize_name (char *fname); uint32 sim_fsize_name (char *fname);
t_addr sim_fsize_ex (FILE *fptr); t_offset sim_fsize_ex (FILE *fptr);
t_addr sim_fsize_name_ex (char *fname); t_offset sim_fsize_name_ex (char *fname);
void sim_buf_swap_data (void *bptr, size_t size, size_t count); 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); void sim_buf_copy_swapped (void *dptr, void *bptr, size_t size, size_t count);
extern uint32 sim_taddr_64; extern t_bool sim_taddr_64; /* t_addr is > 32b and Large File Support available */
extern int32 sim_end; 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 #endif

View file

@ -389,7 +389,7 @@ int32 fdcdrv(int32 io, int32 data)
pos = 0x200; /* Read in SIR */ pos = 0x200; /* Read in SIR */
if (dsk_dev.dctrl & DEBUG_read) if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdcdrv: Read pos = %ld ($%04X)", pos, (unsigned int) pos); 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 */ 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].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */ 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); pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_read) if (dsk_dev.dctrl & DEBUG_read)
printf("\nfdccmd: Read pos = %ld ($%08X)", pos, (unsigned int) pos); 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 */ 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].u3 |= BUSY | DRQ; /* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */ 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); pos += SECSIZ * (dsk_unit[cur_dsk].u5 - 1);
if (dsk_dev.dctrl & DEBUG_write) if (dsk_dev.dctrl & DEBUG_write)
printf("\nfdccmd: Write pos = %ld ($%08X)", pos, (unsigned int) pos); 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 */ wrt_flag = 1; /* set write flag */
dsk_unit[cur_dsk].u3 |= BUSY | DRQ;/* set DRQ & BUSY */ dsk_unit[cur_dsk].u3 |= BUSY | DRQ;/* set DRQ & BUSY */
dsk_unit[cur_dsk].pos = 0; /* clear counter */ dsk_unit[cur_dsk].pos = 0; /* clear counter */