1
0
mirror of https://github.com/simh/simh.git synced 2026-05-03 06:28:41 +00:00

Bob Supnik's state as of 5/9/2015 after backporting some things from the master branch

This commit is contained in:
Mark Pizzolato
2015-05-10 05:48:11 -07:00
parent 3a279c013a
commit 4d48f44857
313 changed files with 80976 additions and 38242 deletions

215
sim_fio.c
View File

@@ -1,6 +1,6 @@
/* sim_fio.c: simulator file I/O library
Copyright (c) 1993-2008, Robert M Supnik
Copyright (c) 1993-2015, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
02-Apr-15 RMS Backported from GitHub master
28-Jun-07 RMS Added VMS IA64 support (from Norm Lastovica)
10-Jul-06 RMS Fixed linux conditionalization (from Chaskiel Grundman)
15-May-06 RMS Added sim_fsize_name
@@ -35,22 +36,27 @@
This library includes:
sim_finit - initialize package
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_fsize - get file size
sim_finit initialize package
sim_fopen open file
sim_fread endian independent read (formerly fxread)
sim_write endian independent write (formerly fxwrite)
sim_fseek (now a macro using fseeko)
sim_fseeko extended seek (>32b if available)
sim_ftell extended tell (>32b if available)
sim_fsize (now a macro using sim_fsize_ex)
sim_fsize_name (now a macro using sim_fsize_ex)
sim_fsize_ex get file size as a t_offset
sim_fsize_name get file size as a t_offset of named file
sim_fopen and sim_fseek are OS-dependent. The other routines are not.
sim_fsize is always a 32b routine (it is used only with small capacity random
access devices like fixed head disks and DECtapes).
sim_fopen, sim_fseeko, sim_ftell are OS-dependent. The other routines are not.
*/
#include "sim_defs.h"
static unsigned char sim_flip[FLIP_SIZE];
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) support available */
/* OS-independent, endian independent binary I/O package
@@ -74,7 +80,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;
}
@@ -134,113 +142,70 @@ return total;
/* Get file size */
uint32 sim_fsize_name (char *fname)
t_offset sim_fsize_ex (FILE *fp)
{
t_offset pos, sz;
if (fp == NULL)
return 0;
pos = sim_ftell (fp);
sim_fseek (fp, 0, SEEK_END);
sz = sim_ftell (fp);
sim_fseeko (fp, pos, SEEK_SET);
return sz;
}
t_offset sim_fsize_name_ex (char *fname)
{
FILE *fp;
uint32 sz;
t_offset sz;
if ((fp = sim_fopen (fname, "rb")) == NULL)
return 0;
sz = sim_fsize (fp);
sz = sim_fsize_ex (fp);
fclose (fp);
return sz;
}
uint32 sim_fsize (FILE *fp)
{
uint32 pos, sz;
if (fp == NULL)
return 0;
pos = ftell (fp);
fseek (fp, 0, SEEK_END);
sz = ftell (fp);
fseek (fp, pos, SEEK_SET);
return sz;
}
/* OS-dependent routines */
/* Optimized file open */
/* Optimized file open
VMS - specify extra goodies
Linux, HP/UX, AIX - use a 64b open if necessary
Others - ordinary open works for 32b or 64b */
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)
#elif (defined (__linux) || defined (__linux__) || defined (__hpux) || defined (_AIX)) && !defined (DONT_DO_LARGEFILE)
return fopen64 (file, mode);
#else
return fopen (file, mode);
#endif
}
/* Long seek */
/* Now define sim_fseeko and sim_ftell */
#if defined (USE_INT64) && defined (USE_ADDR64)
#if !defined (DONT_DO_LARGEFILE)
/* 64b VMS */
/* 64b VMS or Solaris */
#if (defined (__ALPHA) || defined (__ia64)) && defined (VMS) /* 64b VMS */
#define _SIM_IO_FSEEK_EXT_ 1
#if ((defined (__ALPHA) || defined (__ia64)) && defined (VMS) && (__DECC_VER >= 60590001)) || \
((defined(__sun) || defined(__sun__)) && defined(_LARGEFILE_SOURCE))
#define S_SIM_IO_FSEEK_EXT_ 1
static t_int64 fpos_t_to_int64 (fpos_t *pos)
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
unsigned short *w = (unsigned short *) pos; /* endian dep! */
t_int64 result;
result = w[1];
result <<= 16;
result += w[0];
result <<= 9;
result += w[2];
return result;
return fseeko (st, (off_t)offset, whence);
}
static void int64_to_fpos_t (t_int64 ipos, fpos_t *pos, size_t mbc)
t_offset sim_ftell (FILE *st)
{
unsigned short *w = (unsigned short *) pos;
int bufsize = mbc << 9;
w[3] = 0;
w[2] = (unsigned short) (ipos % bufsize);
ipos -= w[2];
ipos >>= 9;
w[0] = (unsigned short) ipos;
ipos >>= 16;
w[1] = (unsigned short) ipos;
if ((w[2] == 0) && (w[0] || w[1])) {
w[2] = bufsize;
w[0] -= mbc;
}
return;
}
int sim_fseek (FILE *st, t_addr offset, int whence)
{
t_addr fileaddr;
fpos_t filepos;
switch (whence) {
case SEEK_SET:
fileaddr = offset;
break;
case SEEK_CUR:
if (fgetpos (st, &filepos))
return (-1);
fileaddr = fpos_t_to_int64 (&filepos);
fileaddr = fileaddr + offset;
break;
default:
errno = EINVAL;
return (-1);
}
int64_to_fpos_t (fileaddr, &filepos, 127);
return fsetpos (st, &filepos);
return (t_offset)(ftello (st));
}
#endif
@@ -248,30 +213,42 @@ return fsetpos (st, &filepos);
/* Alpha UNIX - natively 64b */
#if defined (__ALPHA) && defined (__unix__) /* Alpha UNIX */
#define _SIM_IO_FSEEK_EXT_ 1
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr offset, int whence)
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
return fseek (st, offset, whence);
}
t_offset sim_ftell (FILE *st)
{
return (t_offset)(ftell (st));
}
#endif
/* Windows */
#if defined (_WIN32)
#define _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;
switch (whence) {
case SEEK_SET:
fileaddr = offset;
fileaddr = (fpos_t)offset;
break;
case SEEK_END:
if (_fstati64 (_fileno (st), &statb))
return (-1);
fileaddr = statb.st_size + offset;
break;
case SEEK_CUR:
if (fgetpos (st, &fileaddr))
return (-1);
@@ -286,44 +263,62 @@ switch (whence) {
return fsetpos (st, &fileaddr);
}
t_offset sim_ftell (FILE *st)
{
fpos_t fileaddr;
if (fgetpos (st, &fileaddr))
return (-1);
return (t_offset)fileaddr;
}
#endif /* end Windows */
/* Linux */
/* Linux, HP/UX, and AIX */
#if defined (__linux)
#define _SIM_IO_FSEEK_EXT_ 1
#if defined (__linux) || defined (__linux__) || defined (__hpux) || defined (_AIX)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr xpos, int origin)
int sim_fseeko (FILE *st, t_offset xpos, int origin)
{
return fseeko64 (st, xpos, origin);
return fseeko64 (st, (off64_t)xpos, origin);
}
t_offset sim_ftell (FILE *st)
{
return (t_offset)(ftello64 (st));
}
#endif /* end Linux with LFS */
/* Apple OS/X */
/* Apple OS/X and the BSD family */
#if defined (__APPLE__) || defined (__FreeBSD__)
#define _SIM_IO_FSEEK_EXT_ 1
#if defined (__APPLE__) || defined (__FreeBSD__) || defined(__NetBSD__) || defined (__OpenBSD__)
#define S_SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr xpos, int origin)
int sim_fseeko (FILE *st, t_offset xpos, int origin)
{
return fseeko (st, xpos, origin);
return fseeko (st, (off_t)xpos, origin);
}
t_offset sim_ftell (FILE *st)
{
return (t_offset)(ftello (st));
}
#endif /* end Apple OS/X */
#endif /* end 64b seek defs */
#endif /* !DONT_DO_LARGEFILE */
/* Default: no OS-specific routine has been defined */
#if !defined (_SIM_IO_FSEEK_EXT_)
#define _SIM_IO_FSEEK_EXT_ 0
int sim_fseek (FILE *st, t_addr xpos, int origin)
#if !defined (S_SIM_IO_FSEEK_EXT_)
int sim_fseeko (FILE *st, t_offset xpos, int origin)
{
return fseek (st, (int32) xpos, origin);
return fseek (st, (long) xpos, origin);
}
t_offset sim_ftell (FILE *st)
{
return (t_offset)(ftell (st));
}
#endif
uint32 sim_taddr_64 = _SIM_IO_FSEEK_EXT_;