- ibm1130software.zip was contained within ibm1130.zip from ibm1130.org - Tabs converted to spaces
155 lines
5 KiB
C
155 lines
5 KiB
C
// util_io - I/O routines from simh package -- "endian-independent"
|
|
// borrowed from scp.c, with this copyright notice:
|
|
|
|
// use fxread and fxwrite instead of fread and fwrite
|
|
|
|
/*
|
|
Copyright (c) 1993-2002, 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"),
|
|
to deal in the Software without restriction, including without limitation
|
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
and/or sell copies of the Software, and to permit persons to whom the
|
|
Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
Except as contained in this notice, the name of Robert M Supnik shall not
|
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
|
in this Software without prior written authorization from Robert M Supnik.
|
|
*/
|
|
|
|
/* Endian independent binary I/O package
|
|
|
|
For consistency, all binary data read and written by the simulator
|
|
is stored in little endian data order. That is, in a multi-byte
|
|
data item, the bytes are written out right to left, low order byte
|
|
to high order byte. On a big endian host, data is read and written
|
|
from high byte to low byte. Consequently, data written on a little
|
|
endian system must be byte reversed to be usable on a big endian
|
|
system, and vice versa.
|
|
|
|
These routines are analogs of the standard C runtime routines
|
|
fread and fwrite. If the host is little endian, or the data items
|
|
are size char, then the calls are passed directly to fread or
|
|
fwrite. Otherwise, these routines perform the necessary byte swaps
|
|
using an intermediate buffer.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "util_io.h"
|
|
|
|
#define int32 int
|
|
#define FLIP_SIZE 1024 /* make the flip buffer smaller for these utilities */
|
|
|
|
static int sim_end = 1; /* 1 = little-endian */
|
|
static unsigned char sim_flip[FLIP_SIZE];
|
|
static int end_tested = 0;
|
|
|
|
void util_io_init (void)
|
|
{
|
|
union {int32 i; char c[sizeof (int32)]; } end_test;
|
|
|
|
end_test.i = 1; /* test endian-ness */
|
|
sim_end = end_test.c[0];
|
|
end_tested = 1;
|
|
}
|
|
|
|
size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr)
|
|
{
|
|
size_t c, j, nelem, nbuf, lcnt, total;
|
|
int32 i, k;
|
|
unsigned char *sptr, *dptr;
|
|
|
|
if (! end_tested)
|
|
util_io_init();
|
|
|
|
if (sim_end || (size == sizeof(char)))
|
|
return fread(bptr, size, count, fptr);
|
|
|
|
if ((size == 0) || (count == 0))
|
|
return 0;
|
|
|
|
nelem = FLIP_SIZE / size; /* elements in buffer */
|
|
nbuf = count / nelem; /* number buffers */
|
|
lcnt = count % nelem; /* count in last buf */
|
|
|
|
if (lcnt)
|
|
++nbuf;
|
|
else
|
|
lcnt = nelem;
|
|
|
|
total = 0;
|
|
dptr = bptr; /* init output ptr */
|
|
|
|
for (i = nbuf; i > 0; i--) {
|
|
if ((c = fread(sim_flip, size, (i == 1) ? lcnt : nelem, fptr)) == 0)
|
|
return total;
|
|
|
|
total += c;
|
|
|
|
for (j = 0, sptr = sim_flip; j < c; j++) {
|
|
for (k = size - 1; k >= 0; k--)
|
|
*(dptr + k) = *sptr++;
|
|
|
|
dptr += size;
|
|
}
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr)
|
|
{
|
|
size_t c, j, nelem, nbuf, lcnt, total;
|
|
int32 i, k;
|
|
unsigned char *sptr, *dptr;
|
|
|
|
if (! end_tested)
|
|
util_io_init();
|
|
|
|
if (sim_end || (size == sizeof(char)))
|
|
return fwrite(bptr, size, count, fptr);
|
|
|
|
if ((size == 0) || (count == 0))
|
|
return 0;
|
|
|
|
nelem = FLIP_SIZE / size; /* elements in buffer */
|
|
nbuf = count / nelem; /* number buffers */
|
|
lcnt = count % nelem; /* count in last buf */
|
|
|
|
if (lcnt)
|
|
++nbuf;
|
|
else
|
|
lcnt = nelem;
|
|
|
|
total = 0;
|
|
sptr = bptr; /* init input ptr */
|
|
|
|
for (i = nbuf; i > 0; i--) {
|
|
c = (i == 1) ? lcnt : nelem;
|
|
|
|
for (j = 0, dptr = sim_flip; j < c; j++) {
|
|
for (k = size - 1; k >= 0; k--)
|
|
*(dptr + k) = *sptr++;
|
|
|
|
dptr += size;
|
|
}
|
|
|
|
if ((c = fwrite(sim_flip, size, c, fptr)) == 0)
|
|
return total;
|
|
|
|
total += c;
|
|
}
|
|
|
|
return total;
|
|
}
|