Index: libcio/atoi.c
===================================================================
--- libcio/atoi.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/atoi.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,36 @@
+/*
+   =============================================================================
+	atoi.c -- ascii to integer conversion
+	Version 4 -- 1987-07-09 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stddefs.h"
+#include "ctype.h"
+
+int
+atoi(cp)
+register char *cp;
+{
+	register unsigned i;
+	register short sign;
+
+	sign = 0;
+
+	if ( *cp EQ '-' ) {
+
+		++cp;
+		sign = 1;
+
+	} else {
+
+		if (*cp EQ '+')
+			++cp;
+	}
+
+	for (i = 0; isdigit(*cp); )
+		i = i * 10 + (0x7F & *cp++) - '0';
+
+	return(sign ? -i : i);
+}
+
Index: libcio/atol.c
===================================================================
--- libcio/atol.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/atol.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,35 @@
+/*
+   =============================================================================
+	atol.c -- ascii to long conversion
+	Version 3 -- 1987-06-29 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stddefs.h"
+#include "ctype.h"
+
+long
+atol(cp)
+register char *cp;
+{
+	register long n;
+	register short sign;
+
+	sign = 0;
+
+	if (*cp EQ '-') {
+
+		++cp;
+		sign = 1;
+
+	} else {
+
+		if (*cp EQ '+')
+		++cp;
+	}
+
+	for (n = 0; isdigit(*cp); )
+		n = n * 10 + *cp++ - '0';
+
+	return(sign ? -n : n);
+}
Index: libcio/blkrd.c
===================================================================
--- libcio/blkrd.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/blkrd.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,183 @@
+/*
+   =============================================================================
+	blkrd.c -- read a block of 0..32767 sectors
+	Version 10 -- 1988-01-08 -- D.N. Lynx Crowe
+
+	int
+	blkrd(fcp, buf, ns)
+	struct fcb *fcp;
+	char *buf;
+	int ns;
+
+		Reads 'ns' sectors from file 'fcp' into 'buf'.
+		Returns the number of unread sectors, or 0 if all were read.
+
+	long
+	_secrd(buf, rec)
+	register char *buf;
+	register short rec;
+
+		Reads a logical sector via the track buffer.
+		Functionally equivalent to the BIOS B_RDWR read function
+		with the addition of transparent write-thru track buffering.
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "stddefs.h"
+#include "biosdefs.h"
+#include "errno.h"
+#include "errdefs.h"
+#include "fspars.h"
+
+/* 
+
+*/
+
+#if	DEBUGIT
+extern	short	fsdebug;		/* file system debug switch */
+#endif
+
+extern	int	_nsic();		/* next sector function */
+
+extern	long	_berrno;		/* last file system bios error number */
+
+extern	short	_thefat[];		/* current file allocation table */
+
+extern	struct	bpb	*_thebpb;	/* current bios parameter block */
+
+#if	TBUFFER
+
+/* WARNING:  this ONLY works for 512 byte sectors, 9 sectors per track */
+
+extern	short	_b_tbuf[9][256];	/* the track buffer */
+
+extern	short	_b_trak;		/* current track */
+extern	short	_b_side;		/* current side */
+extern	short	_b_sect;		/* current sector */
+extern	short	_b_tsec;		/* current base sector of current track */
+
+#endif
+
+/* 
+
+*/
+
+#if	TBUFFER
+
+/*
+   =============================================================================
+	_secrd(buf, rec) -- read a logical sector via the track buffer
+   =============================================================================
+*/
+
+long
+_secrd(buf, rec)
+register char *buf;
+register short rec;
+{
+	register short	track, side, sector;
+	long brc;
+
+	if (_thebpb->dspt NE 9)			/* make sure we can do this */
+		return(ERR07);
+
+	if (_thebpb->recsiz NE 512)
+		return(ERR07);
+
+	track = rec / _thebpb->dspc;		/* desired track */
+	_b_tsec = track * _thebpb->dspc;	/* base sector of track */
+	sector = rec - _b_tsec;			/* logical sector in cylinder */
+
+	if (sector GE _thebpb->dspt) {		/* adjust sector and side */
+
+		sector -= _thebpb->dspt;	/* sector now in track */
+		side = 1;
+		_b_tsec += _thebpb->dspt;
+
+	} else {
+
+		side = 0;
+	}
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_secrd($%08.8LX, %d):  track=%d, side=%d, sector=%d, _b_tsec=%d\n",
+			buf, rec, track, side, sector, _b_tsec);
+#endif
+
+	if ((track NE _b_trak) OR (side NE _b_side)) {	/* track in buffer ? */
+
+		if (brc = BIOS(B_RDWR, 0, &_b_tbuf, _thebpb->dspt, _b_tsec, 0)) {
+
+			_b_trak = -1;
+			_b_side = -1;
+			return(brc);
+		}
+
+		_b_trak = track;
+		_b_side = side;
+	}
+
+	memcpy(buf, (char *)_b_tbuf[sector], 512);
+	return(0L);
+}
+
+#endif
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	blkrd(fcp, buf, ns) -- read 'ns' sectors from file 'fcp' into 'buf'.
+	Returns the number of unread sectors, or 0 if all were read.
+   =============================================================================
+*/
+
+int
+blkrd(fcp, buf, ns)
+register struct fcb *fcp;
+register char *buf;
+register int ns;
+{
+	register long	brc;		/* bios return code */
+	register int	rb;		/* _nsic return code */
+
+	if (ns < 0)		/* can't read a negative number of sectors */
+		return(ns);
+
+	while (ns--) {		/* read a sector at a time */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_blkrd():  ns=%d, buf=$%08.8lX, curlsn=%ld, curdsn=%ld, offset=%u\n",
+			ns, buf, fcp->curlsn, fcp->curdsn, fcp->offset);
+#endif
+
+#if	TBUFFER
+		if (brc = _secrd(buf, (short)fcp->curdsn)) {
+#else
+		if (brc = BIOS(B_RDWR, 0, buf, 1, (short)fcp->curdsn, 0)) {
+#endif
+
+			_berrno = brc;		/* log the error */
+			errno = EIO;
+			return(ns);		/* return unread sector count */
+		}
+
+		if (rb = _nsic(fcp, _thebpb, _thefat)) {  /* find next sector */
+
+			if (rb EQ -1)		/* see if we had an error */
+				errno = EIO;	/* set error number */
+
+			return(ns);	/* return unread sector count */
+		}
+
+		buf += _thebpb->recsiz;		/* advance buffer pointer */
+	}
+
+	return(0);	/* return -- all sectors read */
+}
Index: libcio/blkwr.c
===================================================================
--- libcio/blkwr.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/blkwr.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,281 @@
+/*
+   =============================================================================
+	blkwr.c -- write a block of 0..32767 sectors
+	Version 14 -- 1987-12-15 -- D.N. Lynx Crowe
+
+	int
+	blkwr(fcp, buf, ns)
+	struct fcb *fcp;
+	char *buf;
+	int ns;
+
+		Writes 'ns' sectors from file 'fcp' into 'buf'.
+		Returns the number of unwritten sectors,
+		or 0 if all were written.
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "stddefs.h"
+#include "biosdefs.h"
+#include "errno.h"
+#include "errdefs.h"
+#include "fspars.h"
+
+extern	int	_nsic(), _alcnew(), _newcls();
+
+extern	long	_berrno;		/* last file system bios error number */
+
+extern	struct	bpb	*_thebpb;	/* current bios parameter block */
+
+extern	short	_thefat[];		/* current file allocation table */
+
+extern	short	_fatmod;		/* FAT modified flag */
+
+#if DEBUGIT
+extern	short	fsdebug;
+#endif
+
+#if	TBUFFER
+
+/* WARNING:  this ONLY works for 512 byte sectors, 9 sectors per track */
+
+extern	short	_b_tbuf[9][256];	/* the track buffer */
+
+extern	short	_b_trak;		/* current track */
+extern	short	_b_side;		/* current side */
+extern	short	_b_sect;		/* current sector */
+extern	short	_b_tsec;		/* base sector for current track */
+
+#endif
+
+/* 
+
+*/
+
+#if	TBUFFER
+
+/*
+   =============================================================================
+	_secwr(buf, rec) -- write a logical sector into the track buffer
+   =============================================================================
+*/
+
+long
+_secwr(buf, rec)
+register char *buf;
+register short rec;
+{
+	register short	track, side, sector;
+
+	if (_thebpb->dspt NE 9)			/* make sure we can do this */
+		return(ERR07);
+
+	if (_thebpb->recsiz NE 512)
+		return(ERR07);
+
+	track = rec / _thebpb->dspc;		/* desired track */
+	sector = rec - (track * _thebpb->dspc);	/* logical sector */
+
+	if (sector GE _thebpb->dspt) {		/* adjust sector and side */
+
+		sector -= _thebpb->dspt;
+		side = 1;
+
+	} else {
+
+		side = 0;
+	}
+
+#if	DEBUGIT
+	if (fsdebug) {
+
+		printf("_secwr($%08.8LX, %d):  track=%d, side=%d, sector=%d\n",
+			buf, rec, track, side, sector);
+		printf("_secwr():  _b_trak=%d, _b_side=%d, _b_sect=%d, _b_tsec=%d\n",
+			_b_trak, _b_side, _b_sect, _b_tsec);
+	}
+#endif
+
+	if ((track NE _b_trak) OR (side NE _b_side))	/* track in buffer ? */
+		return(0L);
+
+	memcpy((char *)_b_tbuf[sector], buf, 512);	/* update the buffer */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_secwr():  updated track buffer\n");
+#endif
+
+	return(0L);
+}
+
+#endif
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	blkwr(fcp, buf, ns) -- write 'ns' sectors from file 'fcp' into 'buf'.
+	Returns the number of unwritten sectors, or 0 if all were written.
+   =============================================================================
+*/
+
+int
+blkwr(fcp, buf, ns)
+struct fcb *fcp;
+char *buf;
+int ns;
+{
+	long	rc;
+	short	clustr;
+
+	while (ns > 0) {		/* write a sector at a time */
+
+		if (fcp->asects) {
+
+			if (fcp->curlsn LT fcp->asects) {
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  [1] ns=%d, curlsn=%ld, curdsn=%ld, curcls=%u, buf=$%08lX\n",
+			ns, fcp->curlsn, fcp->curdsn, fcp->curcls, buf);
+#endif
+
+				if (rc = BIOS(B_RDWR, 1, buf, 1, (short)fcp->curdsn, 0)) {
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  B_RDWR failed, rc=%ld\n", rc);
+#endif
+
+					_berrno = rc;	/* log the error */
+					errno = EIO;
+					return(ns);	/* return unwritten sector count */
+				}
+
+#if	TBUFFER
+				_secwr(buf, (short)fcp->curdsn);
+#endif
+
+				rc = _nsic(fcp, _thebpb, _thefat);
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  _nsic() rc=%ld\n", rc);
+#endif
+
+				if (--ns EQ 0)		/* done if no more to do */
+					return(0);
+
+				if (rc < 0) {		/* bad cluster ? */
+
+					errno = EIO;	/* set error number */
+					return(ns);	/* return unwritten sector count */
+				}
+
+				buf += _thebpb->recsiz;
+/* 
+
+*/
+			} else if (fcp->curlsn EQ fcp->asects) {
+
+				if (_alcnew(fcp)) {	/* allocate a cluster */
+
+					errno = EIO;	/* set error number */
+					return(ns);	/* return unwritten sector count */
+				}
+
+				fcp->modefl &= ~FC_EOF;	/* clear EOF flag */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  [2] ns=%d, curlsn=%ld, curdsn=%ld, curcls=%u, buf=$%08lX\n",
+			ns, fcp->curlsn, fcp->curdsn, fcp->curcls, buf);
+#endif
+
+				if (rc = BIOS(B_RDWR, 1, buf, 1, (short)fcp->curdsn, 0)) {
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  B_RDWR failed, rc=%ld\n", rc);
+#endif
+
+					_berrno = rc;	/* log the error */
+					errno = EIO;
+					return(ns);	/* return unwritten sector count */
+				}
+
+#if	TBUFFER
+				_secwr(buf, (short)fcp->curdsn);
+#endif
+
+				++fcp->curlsn;
+				++fcp->clsec;
+				++fcp->curdsn;
+
+				if (--ns EQ 0)
+					return(0);
+
+				buf += _thebpb->recsiz;	/* advance buffer pointer */
+			}
+/* 
+
+*/
+		} else {
+
+			if (0 EQ (clustr = _newcls())) {
+
+				errno = EIO;
+				return(ns);
+			}
+
+			fcp->de.bclust = micons(clustr);
+			_ptcl12(_thefat, clustr, 0x0FF8);
+			_fatmod = TRUE;
+			fcp->curdsn = _cl2lsn(_thebpb, clustr);
+			fcp->curcls = clustr;
+			fcp->clsec = 0;
+			fcp->asects = _thebpb->clsiz;
+			fcp->modefl &= ~FC_EOF;
+
+			fcp->modefl &= ~FC_EOF;	/* clear EOF flag */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  [3] ns=%d, curlsn=%ld, curdsn=%ld, curcls=%u, buf=$%08lX\n",
+			ns, fcp->curlsn, fcp->curdsn, fcp->curcls, buf);
+#endif
+
+			if (rc = BIOS(B_RDWR, 1, buf, 1, (short)fcp->curdsn, 0)) {
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("blkwr():  B_RDWR failed, rc=%ld\n", rc);
+#endif
+
+				_berrno = rc;	/* log the error */
+				errno = EIO;
+				return(ns);	/* return unwritten sector count */
+			}
+
+#if	TBUFFER
+			_secwr(buf, (short)fcp->curdsn);
+#endif
+
+			++fcp->curlsn;
+			++fcp->clsec;
+			++fcp->curdsn;
+
+			if (--ns EQ 0)
+				return(0);
+
+			buf += _thebpb->recsiz;	/* advance buffer pointer */
+		}
+	}
+
+	return(ns);	/* return (will be zero or negative) */
+}
Index: libcio/close.c
===================================================================
--- libcio/close.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/close.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,140 @@
+/*
+   =============================================================================
+	close.c -- close a file for the Buchla 700 C I/O Library
+	Version 9 -- 1987-11-13 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+#include "errno.h"
+#include "fcntl.h"
+#include "io.h"
+#include "stddefs.h"
+
+extern	int	_badfd(), ClsFile(), _clsvol();
+
+extern	int	_fatmod, _dirmod;
+extern	struct	bpb	*_thebpb;
+extern	struct	dirent	_thedir[];
+extern	unsigned	_thefat[];
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_clsfat() -- write out the modified FAT
+   =============================================================================
+*/
+
+_clsfat()
+{
+	/* write the primary FAT to disk */
+
+	BIOS(B_RDWR, 1, _thefat, _thebpb->fsiz,
+		_thebpb->fatrec, 0);
+
+	/* write the secondary FAT to disk */
+
+	BIOS(B_RDWR, 1, _thefat, _thebpb->fsiz,
+		(_thebpb->fatrec - _thebpb->fsiz), 0);
+
+	_fatmod = FALSE;	/* FAT on disk now matches memory */
+}
+
+/*
+   =============================================================================
+	_clsdir() -- write out the modified directory
+   =============================================================================
+*/
+
+_clsdir()
+{
+	/* write the directory to disk */
+
+	BIOS(B_RDWR, 1, _thedir, _thebpb->rdlen,
+		(_thebpb->fatrec + _thebpb->fsiz), 0);
+
+	_dirmod = FALSE;	/* directory on disk now matches memory */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	close(fd) -- close file 'fd'
+   =============================================================================
+*/
+
+int
+close(fd)
+int fd;
+{
+	register struct channel *chp;
+	register int rc;
+
+	if ((fd < 0) OR (fd > MAXCHAN)) {
+
+		errno = EBADF;
+		return(FAILURE);
+	}
+
+	chp = &chantab[fd];			/* point at the channel */
+
+	rc  = (*chp->c_close)(chp->c_arg);	/* close the FCB */
+
+	chp->c_read  = 0;			/* release the channel */
+	chp->c_write = 0;
+	chp->c_ioctl = 0;
+	chp->c_seek  = 0;
+	chp->c_close = _badfd;
+
+	if (_fatmod)
+		_clsfat();			/* write modified FAT */
+
+	if (_dirmod)
+		_clsdir();			/* write modified directory */
+
+	return(rc);				/* return result of close */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_filecl(fp) -- close file 'fp' at the BDOS level
+   =============================================================================
+*/
+
+int
+_filecl(fp)
+register struct fcb *fp;
+{
+	register int rc;
+
+	rc = ClsFile(fp);		/* close the FCB */
+	fp->modefl = 0;		/* mark the FILE closed */
+	return(rc);
+}
+
+/*
+   =============================================================================
+	_fd_cls() -- close all open files
+   =============================================================================
+*/
+
+_fd_cls()
+{
+	register int fd;
+
+	for (fd = 0; fd < MAXCHAN; ++fd)
+		if (chantab[fd].c_close NE _badfd)
+			close(fd);
+
+	_clsvol();			/* write modified directory adn FAT */
+}
Index: libcio/clusmap.c
===================================================================
--- libcio/clusmap.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/clusmap.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,413 @@
+/*
+   =============================================================================
+	clusmap.c -- various file structure utilities
+	Version 9 -- 1987-10-29 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+#include "errno.h"
+#include "io.h"
+#include "stdio.h"
+#include "stddefs.h"
+
+extern	int	micons(), _gtcl12();
+extern	long	miconl();
+
+extern	struct	bpb	*_thebpb;
+extern	short	_thefat[];
+
+extern	int	_filecl(), _noper();
+
+/* 
+
+*/
+
+static char	*mfname[] = {	/* FCB flag names */
+
+	"?D0",	/* D0  - 0001 */
+	"?D1",	/* D1  - 0002 */
+	"?D2",	/* D2  - 0004 */
+	"?D3",	/* D3  - 0008 */
+
+	"BF ",	/* D4  - 0010 */
+	"NB ",	/* D5  - 0020 */
+	"TR ",	/* D6  - 0040 */
+	"EX ",	/* D7  - 0080 */
+
+	"RD ",	/* D8  - 0100 */
+	"WR ",	/* D9  - 0200 */
+	"AP ",	/* D10 - 0400 */
+	"CR ",	/* D11 - 0800 */
+
+	"OPN",	/* D12 - 1000 */
+	"ERR",	/* D13 - 2000 */
+	"BAD",	/* D14 - 4000 */
+	"EOF"	/* D15 - 8000 */
+};
+
+/* 
+
+*/
+
+static	char	*dfname[] = {
+
+	"RDONLY",	/* D0 - 01 */
+	"HIDDEN",	/* D1 - 02 */
+	"SYSTEM",	/* D2 - 04 */
+	"VOLUME",	/* D3 - 08 */
+	"SUBDIR",	/* D4 - 10 */
+	"ARCHIV",	/* D5 - 20 */
+	"??D6??",	/* D6 - 40 */
+	"??D7??"	/* D7 - 80 */
+};
+
+static	char	*ffname[] = {
+
+	"BUSY  ",	/* D0 - 01 */
+	"ALLBUF", 	/* D1 - 02 */
+	"DIRTY ", 	/* D2 - 04 */
+	"EOF   ",	/* D3 - 08 */
+	"IOERR ",	/* D4 - 10 */
+	"??D5??",	/* D5 - 20 */
+	"??D6??",	/* D6 - 40 */
+	"??D7??"	/* D7 - 80 */
+};
+
+/* 
+
+*/
+
+static int
+waitcr()
+{
+	char	c;
+
+	BIOS(B_PUTC, CON_DEV, '\007');
+
+	while ('\r' NE (c = (0x7F & BIOS(B_GETC, CON_DEV))))
+		if (c EQ '\007')
+			xtrap15();
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	ClusMap(fcp) -- print a map of the clusters for the file associated with
+	the FCB pointed to by 'fcp'.  Nothing is printed if the file isn't open.
+	Returns 0 if a map was printed, -1 otherwise.
+   =============================================================================
+*/
+
+int
+ClusMap(fcp)
+struct fcb *fcp;
+{
+	int	clus, nc;
+	long	alsize, bused, bunused;
+
+	if (!(fcp->modefl & FC_OPN)) {
+
+		errno = EINVAL;
+		return(FAILURE);
+	}
+
+	nc = 0;
+	clus = micons(fcp->de.bclust);
+
+	if (clus) {
+
+		printf("Allocated cluster chain for [%-8.8s].[%-3.3s]:\n%6d",
+			fcp->de.fname, fcp->de.fext, clus);
+		nc = 1;	
+
+		while (clus < 0xFF0) {
+
+			clus = _gtcl12(_thefat, clus);
+
+			if (clus < 0xFF0) {
+
+				nc++;
+
+				if (0 EQ (nc-1) % 10)
+					printf("\n");
+
+				printf("%6d", clus);
+			}
+		}
+	}
+
+	alsize = nc * _thebpb->clsizb;
+	bused = fcp->curlen;
+	bunused = alsize - bused;
+
+	printf("\nFAT cluster count=%d, asects=%ld\n", nc, fcp->asects);
+	printf("%ld bytes allocated, %ld bytes used", alsize, bused);
+
+	if (alsize GE bused)
+		printf(", %ld bytes unused", bunused);
+
+	printf("\n");
+
+	if (bused GT alsize)
+		printf("ERROR:  directory file size exceeds FAT allocation\n");
+
+	if (fcp->asects NE nc)
+		printf("ERROR:  FAT cluster count (%d) NE FCB cluster count (%ld)\n",
+			nc, fcp->asects);
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	FCBmode(fcp) -- print FCB mode flags
+   =============================================================================
+*/
+
+struct fcb *
+FCBmode(fcp)
+register struct fcb *fcp;
+{
+	register unsigned short mf;
+	register short i;
+
+	printf("  flags:  ");
+	mf = 0x0001;
+
+	for (i = 0; i < 16; i++) {
+
+		if (fcp->modefl & mf)
+			printf("%s ", mfname[i]);
+
+		mf <<= 1;
+	}
+
+	printf("\n  atrib:  ");
+
+	mf = 0x01;
+
+	for (i = 0; i < 8; i++) {
+
+		if (fcp->de.atrib & mf)
+			printf("%s ", dfname[i]);
+
+		mf <<= 1;
+	}
+
+	printf("\n");
+	return(fcp);
+}
+
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	SnapFCB(fcp) -- print contents of an FCB pointed to by 'fcp'
+   =============================================================================
+*/
+
+struct fcb *
+SnapFCB(fcp)
+register struct fcb *fcp;
+{
+	printf("\nFCB at 0x%08lx:  [%-8.8s].[%-3.3s]\n",
+		fcp, fcp->de.fname, fcp->de.fext);
+	FCBmode(fcp);
+
+	printf("  atrib      0x%04x",	fcp->de.atrib);
+	printf("  modefl     0x%04x\n",	fcp->modefl);
+
+	printf("  crtime     0x%04x",	micons(fcp->de.crtime));
+	printf("  crdate     0x%04x\n",	micons(fcp->de.crdate));
+
+	printf("  asects   %8ld",	fcp->asects);
+	printf("  flen     %8ld",	miconl(fcp->de.flen));
+	printf("  curlen   %8ld\n",	fcp->curlen);
+
+	printf("  bclust   %8d",	micons(fcp->de.bclust));
+	printf("  curcls   %8d",	fcp->curcls);
+	printf("  clsec    %8d\n",	fcp->clsec);
+
+	printf("  curlsn   %8ld",	fcp->curlsn);
+	printf("  curdsn   %8ld",	fcp->curdsn);
+	printf("  offset   %8d\n",	fcp->offset);
+
+	printf("\n");
+	return(fcp);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	MapFAT() -- print the first 'ncl' cluster entries from 'fat'
+   =============================================================================
+*/
+
+MapFAT(fat, ncl, stops)
+register char *fat;
+short ncl, stops;
+{
+	register int i;
+
+	printf("\nCluster dump of FAT at 0x%08.8lx  (%d entries):\n",
+		fat, ncl);
+	printf("   0: .... .... ");
+
+	for (i = 2; i < ncl; i++) {
+
+		if ((i % 10) EQ 0)
+			printf("\n%4.4d: ", i);
+
+		printf("%4.4d ", _gtcl12(fat, i));
+
+		/* stop every 10 lines if requested */
+
+		if (stops AND (((i / 10) % 10) EQ 0))
+			waitcr();
+	}
+
+	printf("\n");
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	FILEfl() -- print FILE flags
+   =============================================================================
+*/
+
+FILE *
+FILEfl(fp)
+FILE *fp;
+{
+	register unsigned short mf;
+	register short i;
+
+	printf("  _flags:  ");
+	mf = 0x0001;
+
+	for (i = 0; i < 8; i++) {
+
+		if (fp->_flags & mf)
+			printf("%s ", ffname[i]);
+
+		mf <<= 1;
+	}
+
+	printf("\n");
+	return(fp);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	FILEpr(fp) -- print contents of a FILE structure pointed to by 'fp'
+   =============================================================================
+*/
+
+FILEpr(fp)
+FILE *fp;
+{
+	int	(*arg)(), ft;
+	char	*ds, *fsn, *fse;
+	struct	fcb	*fcp;
+
+	if (fp EQ (FILE *)0L) {
+
+		printf("FILEpr():  ERROR - argument was NULL\n");
+		return;
+	}
+
+
+	printf("\nFILE at $%08.8lX", fp);
+
+	arg = chantab[fp->_unit].c_close;
+	ft = 0;
+
+	if (arg EQ _noper) {
+
+		ds = (struct device *)chantab[fp->_unit].c_arg->d_name;
+		printf(" is a device:  [%s]\n", ds);
+
+	} else if (arg EQ _filecl) {
+
+		ft = 1;
+		fcp = (struct fcb *)chantab[fp->_unit].c_arg;
+		fsn = fcp->de.fname;
+		fse = fcp->de.fext;
+		printf(" is a disk file:  [%8.8s].[%3.3s],  fcb at $%08.8lX\n",
+			fsn, fse, fcp);
+
+	} else {
+
+		printf(" is of UNKNOWN type: c_close=$%08.8lX, c_arg=$%08.8lX\n",
+			arg, chantab[fp->_unit].c_arg);
+	}
+
+	printf("  _buff=$%08.8lX, _bp=$%08.8lX, _bend=$%08.8lX, _buflen=%u\n",
+		fp->_buff, fp->_bp, fp->_bend, fp->_buflen);
+	printf("  _flags=$%04.4X, _unit=%d, _bytbuf=$%02.2X\n",
+		fp->_flags, fp->_unit, fp->_bytbuf);
+
+	FILEfl(fp);
+
+	if (ft)
+		SnapFCB(fcp);
+	else
+		printf("\n");
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	fd2fcb() -- convert a unit number to a pointer to a fcb
+   =============================================================================
+*/
+
+struct fcb *
+fd2fcb(fd)
+short fd;
+{
+	if ((fd < 0) OR (fd > MAXCHAN))
+		return((struct fcb *)NULL);
+
+	return(chantab[fd].c_arg);
+}
+
+/*
+   =============================================================================
+	fp2fcb() -- convert a FILE pointer to a pointer to a fcb
+   =============================================================================
+*/
+
+struct fcb *
+fp2fcb(fp)
+FILE *fp;
+{
+	if (fp EQ (FILE *)NULL)
+		return((struct fcb *)NULL);
+
+	return(chantab[fp->_unit].c_arg);
+}
Index: libcio/conin.c
===================================================================
--- libcio/conin.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/conin.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,56 @@
+/*
+   =============================================================================
+	conin.c -- read from the console
+	Version 6 -- 1987-06-30 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#define	_FS_DEF_		/* to avoid unnecessary externals */
+
+#include "biosdefs.h"
+#include "io.h"
+#include "errno.h"
+#include "fcntl.h"
+#include "stddefs.h"
+
+extern	char	*memcpy();
+extern	int	readbuf(), writeln();
+
+char _ConBuf[258];	/* console input buffer */
+int _CBused;
+
+int
+_conin(x, buff, len)
+char *buff;
+{
+	int 	nbp;
+	register int l;
+
+	if (_ConBuf[1] EQ 0) {
+
+		_ConBuf[0] = 255;
+		_ConBuf[1] = _ConBuf[2] = 0;
+
+		readbuf(CON_DEV, _ConBuf);
+		writeln(CON_DEV, "\r\n");
+
+		if (_ConBuf[2] EQ 0x1a) {
+
+			_ConBuf[1] = 0;
+			return(0);
+		}
+
+		nbp = ++_ConBuf[1];
+		_ConBuf[nbp++ + 1] = '\r';
+		_ConBuf[nbp + 1] = '\n';
+		_CBused = 2;
+	}
+
+	if ((l = _ConBuf[1]) > len)
+		l = len;
+
+	memcpy(buff, (_ConBuf + _CBused), l);
+	_CBused += l;
+	_ConBuf[1] -= l;
+	return (l);
+}
Index: libcio/conwr.c
===================================================================
--- libcio/conwr.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/conwr.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,33 @@
+/*
+   ============================================================================
+	conwr.c -- write on the console
+	Version 4 -- 1987-06-29 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#define	_FS_DEF_		/* to avoid unnecessary externals */
+
+#include "biosdefs.h"
+#include "io.h"
+#include "errno.h"
+#include "stddefs.h"
+
+/*
+   ============================================================================
+	_conwr(kind, buff, len) -- write 'len' bytes from 'buff' on the console
+	using op 'kind' as the BIOS argument.
+   ============================================================================
+*/
+int
+_conwr(kind, buff, len)
+int kind;
+register char *buff;
+int len;
+{
+	register int count;
+
+	for (count = 0; count < len; ++count)
+		BIOS(B_PUTC, kind, *buff++);
+
+	return(count);
+}
Index: libcio/dirfns.c
===================================================================
--- libcio/dirfns.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/dirfns.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,145 @@
+/*
+   =============================================================================
+	dirfns.c -- miscellaneous directory functions
+	Version 4 -- 1987-06-04 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stddefs.h"
+#include "biosdefs.h"
+
+extern	int	sprintf();
+
+static char atrcons[] = "ADVSHR";
+
+/*
+   =============================================================================
+	atrstr(atr, s) -- convert attributes to character string
+   =============================================================================
+*/
+
+char *
+atrstr(atr, s)
+register short atr;
+register char s[];
+{
+	register short	i, j;
+
+	i = 0x20;
+
+	for (j = 0; j < 6; j++) {
+
+		if (atr & i)
+			s[j] = atrcons[j];
+		else
+			s[j] = '-';
+
+		i >>= 1;
+	}
+
+	s[j] = '\0';
+	return(s);
+}
+
+/* 
+ */
+
+static char *mnames[] = {
+
+	"???",
+	"Jan",
+	"Feb",
+	"Mar",
+	"Apr",
+	"May",
+	"Jun",
+	"Jul",
+	"Aug",
+	"Sep",
+	"Oct",
+	"Nov",
+	"Dec"
+	};
+
+/*
+   =============================================================================
+	mname - convert month number to month name
+   =============================================================================
+*/
+
+char *
+mname(n)
+short n;
+{
+	return((n < 1 || n > 12) ? mnames[0] : mnames[n]);
+}
+
+/* 
+ */
+
+/*
+   =============================================================================
+	dtunpk(din, tin, s, fmt) -- unpack the date and time from DOS format
+	into "yyyy-mm-dd hh:mm", "yyyy mmm dd hh:mm", or "mmm dd yyyy hh:mm"
+	format.
+   =============================================================================
+*/
+
+char *
+dtunpk(din, tin, s, fmt)
+short din, tin, fmt;
+char *s;
+{
+	register short	ftm, fdt;
+
+	ftm = ((tin << 8) & 0xFF00) | ((tin >> 8) & 0x00FF);
+	fdt = ((din << 8) & 0xFF00) | ((din >> 8) & 0x00FF);
+
+	switch (fmt) {
+
+	case 0:		/* yyyy-mm-dd hh:mm format */
+
+		sprintf(s, "%04d-%02d-%02d %02d:%02d",
+			1980 + ((fdt >> 9) & 0x7F),
+			(fdt >> 5) & 0xF,
+			fdt & 0x1F,
+			(ftm >> 11) & 0x1F,
+			(ftm >> 5) & 0x3F
+			);
+
+		s[16] = '\0';
+		break;
+
+	case 1:		/* yyyy mmm dd hh:mm format */
+	default:
+
+		sprintf(s, "%04d %s %-2d %02d:%02d",
+			1980 + ((fdt >> 9) & 0x7F),
+			mname((fdt >> 5) & 0xF),
+			fdt & 0x1F,
+			(ftm >> 11) & 0x1F,
+			(ftm >> 5) & 0x3F
+			);
+
+		s[17] = '\0';
+		break;
+
+/* 
+ */
+
+	case 2:		/* mmm dd yyyy hh:mm format */
+
+		sprintf(s, "%s %2d %04d %02d:%02d",
+			mname((fdt >> 5) & 0xF),
+			fdt & 0x1F,
+			1980 + ((fdt >> 9) & 0x7F),
+			(ftm >> 11) & 0x1F,
+			(ftm >> 5) & 0x3F
+			);
+
+		s[17] = '\0';
+		break;
+	}
+
+	return(s);
+}
Index: libcio/fgets.c
===================================================================
--- libcio/fgets.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fgets.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,83 @@
+/*
+   =============================================================================
+	fgets.c -- get a string from an ASCII stream file
+	Version 2 -- 1987-07-09 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+#define	EATCHAR	'\n'	/* character to be "eaten" on input */
+
+int
+agetc(ptr)
+register FILE *ptr;
+{
+	register int c;
+
+top:
+	if ((c = getc(ptr)) NE EOF) {
+
+		switch (c &= 0x7F) {
+
+		case 0x1a:		/* {x}DOS EOF */
+			--ptr->_bp;
+			return(EOF);
+
+		case EATCHAR:		/* CR or LF */
+		case 0:			/* NUL */
+			goto top;
+		}
+	}
+
+	return(c);
+}
+
+char *
+gets(line)
+char *line;
+{
+	register char *cp;
+	register int i;
+
+	cp = line;
+
+	while ((i = getchar()) NE EOF AND i NE '\n')
+		*cp++ = i;
+
+	*cp = 0;	/* terminate the line */
+
+	if ((i EQ EOF) AND (cp EQ line))
+		return(NULL);
+
+	return(line);
+}
+
+char *
+fgets(s, n, fp)
+char *s;
+int n;
+FILE *fp;
+{
+	register c;
+	register char *cp;
+
+	cp = s;
+
+	while (--n > 0 AND (c = agetc(fp)) NE EOF) {
+
+		*cp++ = c;
+
+		if (c EQ '\n')
+			break;
+	}
+
+	*cp = 0;
+
+	if (c EQ EOF AND cp EQ s)
+		return(NULL);
+
+	return(s);
+}
+
Index: libcio/filesys.c
===================================================================
--- libcio/filesys.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/filesys.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,1236 @@
+/*
+   =============================================================================
+	filesys.c -- file system support functions
+	Version 44 -- 1987-11-15 -- D.N. Lynx Crowe
+
+	These functions support a {MS,GEM}DOS|TOS-like file system.
+	Only 12 bit FAT entries are supported.
+	Subdirectories are not supported in this version.
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#define	_FS_DEF_	/* to avoid unnecessary externals */
+
+#include "stddefs.h"
+#include "biosdefs.h"
+#include "errno.h"
+#include "memory.h"
+#include "io.h"
+#include "fcntl.h"
+
+#define	FAT_EOF		0x0FF8
+
+#define	IO_ERR		-1
+#define	IO_OK		0
+#define	IO_EOF		1
+
+#define	DE_NULL		((struct dirent *)0L)
+
+extern	unsigned micons();
+extern	long	miconl();
+extern	int	_ptcl12();
+extern	char	*FilName(), *FilExt();
+
+#if DEBUGIT
+short	fsdebug;
+extern	int	mdump();
+#endif
+
+struct	bpb	*_thebpb;		/* BIOS parameter block pointer */
+struct	dirent	_thedir[MAXDIRNT];	/* directory */
+struct	dirent	*_dptr;			/* internal directory pointer */
+
+unsigned _thefat[MAXFAT * WDPSEC];	/* file allocation table */
+
+int	_fatin;				/* FAT has been read */
+int	_dirin;				/* directory has been read */
+int	_bpbin;				/* BPB has been read */
+int	_fatmod;			/* FAT modified flag */
+int	_dirmod;			/* directory modified flag */
+
+long	_berrno;			/* BIOS error number */
+
+/* 
+
+*/
+
+
+/*
+   =============================================================================
+	_cl2lsn(bpp, clnum) -- return logical sector number for cluster 'clnum'
+	using BPB pointed to by 'bpp'
+   =============================================================================
+*/
+
+unsigned
+_cl2lsn(bpp, clnum)
+struct bpb *bpp;
+unsigned clnum;
+{
+	return(bpp->datrec + (bpp->clsiz * (clnum - 2)) );
+}
+
+/*
+   =============================================================================
+	_gtcl12(fat, cl) -- return 12 bit cluster entry 'cl' from FAT pointed
+	to by 'fat'
+   =============================================================================
+*/
+
+unsigned
+_gtcl12(fat, cl)
+register char *fat;
+unsigned cl;
+{
+	register unsigned cla, clt;
+
+	cla = cl + (cl >> 1);
+	clt = ((unsigned)0xFF00 & (fat[cla+1] << 8))
+		| ((unsigned)0x00FF & fat[cla]);
+
+	if (cl & 1)
+		clt >>= 4;
+
+	clt &= (unsigned)0x0FFF;
+	return(clt);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_getfat(bufad, bpp, nfat) -- get FAT 'nfat' into buffer
+	pointed to by 'bufad' using BPB pointed to by 'bpp'
+   =============================================================================
+*/
+
+unsigned
+_getfat(bufad, bpp, nfat)
+unsigned *bufad, nfat;
+register struct bpb *bpp;
+{
+	unsigned fatsec;
+
+	fatsec = nfat ? bpp->fatrec : (bpp->fatrec - bpp->fsiz);
+	return(BIOS(B_RDWR, 0, (char *)bufad, bpp->fsiz, fatsec, 0));
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_rdfat(bufad, bpp) -- read FAT into buffer pointed to by 'bufad'
+	using BPB pointed to by 'bpp'
+   =============================================================================
+*/
+
+int
+_rdfat(bufad, bpp)
+unsigned *bufad;
+struct bpb *bpp;
+{
+	if (_getfat(bufad, bpp, 0)) {
+
+		if (_getfat(bufad, bpp, 1))
+			return(IO_ERR);		/* couldn't read either FAT */
+		else
+			return(1);		/* secondary FAT read OK */
+
+	} else
+		return(0);			/* main FAT read OK */
+}
+
+/*
+   =============================================================================
+	_rdroot(buf, bpp) -- read root directory into buffer
+	pointed to by 'buf' using BPB pointed to by 'bpp'
+   =============================================================================
+*/
+
+int
+_rdroot(buf, bpp)
+unsigned *buf;
+register struct bpb *bpp;
+{
+	return(BIOS(B_RDWR, 0, (char *)buf, bpp->rdlen,
+		(bpp->fatrec + bpp->fsiz), 0));
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_nsic(fcp, bpp, fp) -- get the next sector in the file controlled
+	by the FCB at 'fcp', using the BPB pointed to by 'bpp' and
+	the FAT pointed to by 'fp'.  Returns 0 if successful, or -1 on error,
+	or 1 on EOF;
+   =============================================================================
+*/
+
+int
+_nsic(fcp, bpp, fp)
+register struct fcb *fcp;
+struct bpb *bpp;
+char *fp;
+{
+	register unsigned tfe;
+
+	/* check the FCB flags */
+
+	if (!(fcp->modefl & FC_OPN)) {
+
+		errno = EINVAL;		/* not open */
+		return(IO_ERR);
+	}
+
+	if (fcp->modefl & FC_BAD) {
+
+		errno = EIO;		/* previous I/O error */
+		return(IO_ERR);
+	}
+
+	if (fcp->de.bclust EQ 0) {	/* no sectors allocated  (empty file) */
+
+		fcp->modefl |= FC_EOF;
+		return(IO_EOF);
+	}
+/* 
+
+*/
+	/* update clsec and curlsn and see if we need a new cluster */
+
+	++fcp->curlsn;
+
+	if (++fcp->clsec GE bpp->clsiz) {
+
+		/* new cluster needed -- follow the chain */
+
+		fcp->clsec = 0;
+		tfe = _gtcl12(fp, fcp->curcls);
+
+		if (tfe < 0x0FF0) {	/* see if we've got a good cluster */
+
+
+			fcp->curcls = tfe;	/* good cluster, update fcb */
+			fcp->curdsn = _cl2lsn(bpp, tfe);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_nsic():  NXT curlsn=%ld, curcls=%u, curdsn=%ld\n",
+			fcp->curlsn, fcp->curcls, fcp->curdsn);
+#endif
+
+			return(IO_OK);
+		}
+
+		if (tfe < 0x0FF8) {	/* see if it's a bad cluster */
+
+			fcp-> modefl |= (FC_BAD | FC_EOF);	/* bad one */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_nsic():  IO_ERR - curlsn=%ld, curcls=%u, curdsn=%ld\n",
+			fcp->curlsn, fcp->curcls, fcp->curdsn);
+#endif
+
+			return(IO_ERR);
+		}
+
+		fcp->modefl |= FC_EOF;	/* EOF hit -- set EOF in FCB */
+		return(IO_EOF);
+
+/* 
+
+*/
+
+	} else {
+
+		++fcp->curdsn;	/* advance to next sector in current cluster */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_nsic():  CUR curlsn=%ld, curcls=%u, curdsn=%ld\n",
+			fcp->curlsn, fcp->curcls, fcp->curdsn);
+#endif
+
+		return(IO_OK);
+	}
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_dsrch(de) -- search for the directory entry pointed to by 'de'
+	in the current directory
+   =============================================================================
+*/
+
+struct dirent *
+_dsrch(de)
+register struct dirent *de;
+{
+	unsigned i, dl;
+	register struct dirent *dp;
+
+	dp = _thedir;
+	dl = _thebpb->rdlen * (_thebpb->recsiz / DENTSIZE);
+
+	for (i = 0; i < dl; i++) {		/* check each entry */
+
+		/* see if we've found it */
+
+		if (0 EQ memcmpu(de->fname, dp->fname, 11))
+			return(dp);
+
+		/* check for end of used entries */
+
+		if ('\0' EQ dp->fname[0])
+			return(DE_NULL);
+
+		dp++;	/* point at next entry to check */
+	}
+
+	return(DE_NULL);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_dsnew() -- search for an available directory entry in the current
+	directory.
+   =============================================================================
+*/
+
+struct dirent *
+_dsnew()
+{
+	unsigned i, dl;
+	register struct dirent *dp;
+
+	dp = _thedir;
+	dl = _thebpb->rdlen * (_thebpb->recsiz / DENTSIZE);
+
+	for (i = 0; i < dl; i++) {		/* check each entry */
+
+		/* check for a deleted entry */
+
+		if (0x00E5 EQ (0x00FF & dp->fname[0]))
+			return(dp);
+
+		/* check for end of used entries */
+
+		if ('\0' EQ dp->fname[0])
+			return(dp);
+
+		dp++;	/* point at next entry to check */
+	}
+
+	return(DE_NULL);	/* couldn't find an available entry */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_deadio(fcp, err) -- mark the FCB pointed to by 'fcp' as 'in error'
+   =============================================================================
+*/
+
+_deadio(fcp, err)
+register struct fcb *fcp;
+int err;
+{
+	fcp->clsec = 0;
+	fcp->curcls = 0;
+	fcp->curlsn = 0L;
+	fcp->curdsn = 0L;
+	fcp->curlen = 0L;
+	fcp->modefl &= ~FC_OPN;
+	fcp->modefl |= FC_ERR;
+	errno = err;
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_seek(fcp) -- seek to logical sector number in FCB pointed to by 'fcp'.
+	Returns:  -1 = error; 0 = not at EOF; 1 = soft EOF; 2 = hard EOF.
+   =============================================================================
+*/
+
+int
+_seek(fcp)
+register struct fcb *fcp;
+{
+	register unsigned acls, rcls, nc;
+	unsigned sic, spc;
+
+	if (!(fcp->modefl & FC_OPN)) {		/* file must be open */
+
+		errno = EINVAL;			/* invalid request */
+		return(-1);			/* return with an error */
+	}
+
+	if (fcp->curlsn GT fcp->asects) {	/* error if seek past EOF */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_seek():  ERROR - seek past EOF - curlsn=%ld, asects=%ld\n",
+			fcp->curlsn, fcp->asects);
+#endif
+
+		errno = EINVAL;			/* invalid request */
+		return(-1);			/* return with an error */
+	}
+		
+	spc = _thebpb->clsiz;			/* get sectors per cluster */
+	rcls = fcp->curlsn / spc;		/* calculate relative cluster */
+	sic = fcp->curlsn - (rcls * spc);	/* calculate sector in cluster */
+	acls = micons(fcp->de.bclust);		/* get first cluster */
+	fcp->modefl &= ~FC_EOF;			/* turn off the EOF flag */
+
+/* 
+
+*/
+
+#if DEBUGIT
+	if (fsdebug) {
+		printf("_seek():  ENTRY curlsn=%ld, acls=%u, sic=%d, curdsn=%ld, rcls=%u, asects=%ld\n",
+			fcp->curlsn, acls, sic, fcp->curdsn, rcls, fcp->asects);
+	}
+#endif
+
+	if (fcp->curlsn EQ fcp->asects) {	/* see if we seeked to EOF */
+
+		fcp->modefl |= FC_EOF;		/* flag the EOF condition */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_seek():  EOF curlsn=%ld, acls=%u, sic=%d, curdsn=%ld\n",
+			fcp->curlsn, acls, sic, fcp->curdsn);
+#endif
+
+		if (acls EQ 0)			/* see if anything allocated */
+			return(2);		/* hard EOF if nothing there */
+
+		if (sic EQ 0)			/* see if first in cluster */
+			return(2);		/* hard EOF if so */
+	}
+
+/* 
+
+*/
+	for (nc = 0; nc < rcls; nc++) {		/* follow the FAT chain */
+
+		acls = _gtcl12(_thefat, acls);	/* next cluster pointer */
+
+		if (acls LT 0x0FF0)		/* OK if it's a good cluster */
+			continue;
+
+		fcp->modefl |= FC_ERR;		/* EOF or bad cluster hit */
+		errno = EINVAL;			/* mark it as an invalid seek */
+
+		if (acls LT 0x0FF8) {		/* bad cluster ? */
+
+			errno = EIO;		/* mark it as an I/O error */
+			fcp->modefl |= FC_BAD;	/* mark FCB:  bad cluster hit */
+		}
+
+		return(IO_ERR);			/* ERROR:  seek error */
+	}
+
+	fcp->curcls = acls;			/* current cluster */
+	fcp->clsec = sic;			/* sector in cluster */
+
+	fcp->curdsn = _cl2lsn(_thebpb, acls) + sic;	/* disk sector number */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_seek():  OK curlsn=%ld, acls=%u, sic=%d, curdsn=%ld\n",
+			fcp->curlsn, acls, sic, fcp->curdsn);
+#endif
+
+	if (fcp->curlsn EQ fcp->asects)		/* see if we're at EOF */
+		return(1);			/* soft EOF */
+		
+	return(0);				/* not EOF */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_ftrnc(dp) -- truncate file pointed to by directory entry 'dp'
+   =============================================================================
+*/
+
+int
+_ftrnc(dp)
+struct dirent *dp;
+{
+	register unsigned acls, ncls;
+
+#if	DEBUGIT
+	register int lim;
+
+	lim = _thebpb->numcl;
+#endif
+
+	acls = micons(dp->bclust);		/* get first cluster number */
+
+	/* zap entries until EOF or bad cluster */
+
+#if	DEBUGIT
+	while (lim-- AND (acls LT 0x0FF0)) {
+#else
+	while (acls LT 0x0FF0) {
+#endif
+
+		ncls = _gtcl12(_thefat, acls);	/* get next cluster number */
+		_ptcl12(_thefat, acls, 0);	/* zap the current one */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_ftrnc():  zapped %d\n", acls);
+#endif
+
+		acls = ncls;			/* point at the next one */
+	}
+
+/* 
+
+*/
+
+	dp->flen = 0L;				/* file length = 0 */
+	dp->bclust = 0;				/* no sectors allocated */
+	_fatmod = TRUE;				/* FAT got changed */
+	_dirmod = TRUE;				/* directory got changed */
+
+#if	DEBUGIT
+	if (lim LE 0) {
+
+		errno = EIO;
+		printf("_ftrnc():  ERROR - lim went to %d\n", lim);
+		mdump(_thefat, (char *)_thefat+255, _thefat);
+		xtrap15();
+		return(FAILURE);
+	}
+#endif
+
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_newcls() -- allocate a new cluster
+   =============================================================================
+*/
+
+int
+_newcls()
+{
+	register int tc, i;
+
+	tc = _thebpb->numcl;
+
+	for (i = 2; i < tc; i++)
+		if (0 EQ _gtcl12(_thefat, i))
+			return(i);
+
+	return(0);	/* ERROR:  no empty clusters left */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_alcnew() -- allocate a new cluster to extend a file
+   =============================================================================
+*/
+
+int
+_alcnew(fcp)
+register struct fcb *fcp;
+{
+	register int ac, nc, pc;
+
+#if	DEBUGIT
+	register int lim;
+#endif
+
+	if (nc = _newcls()) {			/* get a new cluster */
+
+#if	DEBUGIT
+		lim = (fcp->asects / _thebpb->clsiz) + 1;  /* limit search */
+#endif
+
+		_ptcl12(_thefat, nc, FAT_EOF);	/* mark new cluster as EOF */
+		pc = micons(fcp->de.bclust);	/* get first cluster */
+
+#if	DEBUGIT
+	if (pc EQ 0) {
+
+		printf("_alcnew():  ERROR - pc EQ 0, bclust=$%04.4X, nc=%d\n",
+			fcp->de.bclust, nc);
+		xtrap15();
+	}
+#endif
+
+		/* find end of allocation chain */
+
+#if	DEBUGIT
+		while (lim-- AND ((ac = _gtcl12(_thefat, pc)) < 0x0FF0)) {
+#else
+		while ((ac = _gtcl12(_thefat, pc)) < 0x0FF0) {
+#endif
+
+			pc = ac;
+		}
+
+/* 
+
+*/
+
+#if	DEBUGIT
+		if (lim LE 0) {
+
+			printf("_alcnew():  ERROR - lim ran out, nc=%d\n", nc);
+			mdump(_thefat, (char *)_thefat+63, _thefat);
+			xtrap15();
+			return(FAILURE);
+		}
+#endif
+
+		_ptcl12(_thefat, pc, nc);	/* add cluster to chain */
+		fcp->asects += _thebpb->clsiz;	/* update allocated sector count */
+		fcp->curcls = nc;		/* current cluster = new cluster */
+		fcp->clsec = 0;			/* current sector in cluster = 0 */
+
+		fcp->curdsn = _cl2lsn(_thebpb, nc);	/* current disk sector */
+
+#if DEBUGIT
+		if (fsdebug) {
+
+			printf("alcnew():  allocated cluster %d (%04.4x), ",
+				nc, nc);
+			printf("previous = %d (%04.04x), asects =%ld\n",
+				pc, pc, fcp->asects);
+		}
+#endif
+
+		return(SUCCESS);		/* return:  file extended */
+
+	} else {
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_alcnew():  _newcls() FAILED\n");
+#endif
+
+		return(FAILURE);		/* return:  no clusters left */
+	}
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_fmake(fcp) -- make a new file from the FCB pointed to by 'fcp'
+   =============================================================================
+*/
+
+int
+_fmake(fcp)
+struct fcb *fcp;
+{
+	register struct dirent *dp;
+
+	if (DE_NULL EQ (dp = _dsnew()))		/* find a dirent */
+		return(FAILURE);
+
+	_dptr = dp;				/* set the directory pointer */
+	memset(dp, 0, DENTSIZE);		/* clear the dirent */
+	memcpy(dp->fname, fcp->de.fname, 12);	/* setup file name, attribute */
+	dp->atrib |= F_ARCHIV;			/* set the archive bit */
+	_dirmod = TRUE;				/* directory got changed */
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_opnvol() -- open a volume
+   =============================================================================
+*/
+
+int
+_opnvol()
+{
+	register long drc;
+
+	/* check for media change if we already have a BPB */
+
+	if (_bpbin) {
+
+		drc = BIOS(B_MCHG, 0);
+
+#if DEBUGIT
+	if (fsdebug) {
+
+		printf("_opnvol():  found _bpbin FALSE\n");
+		printf("_opnvol():  disk change test returned %ld\n", drc);
+	}
+#endif
+
+		if (drc)
+			_bpbin = FALSE;
+	} else {
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_opnvol():  found _bpbin FALSE\n");
+#endif
+
+	}
+
+	if (!_bpbin) {		/* access the BPB */
+
+		_fatin = FALSE;		/* invalidate the FAT and directory */
+		_dirin = FALSE;
+
+		if ((struct bpb *)0L EQ (_thebpb = BIOS(B_GBPB, 0))) {
+
+			errno = EIO;	/* couldn't read the BPB */
+			return(FAILURE);
+		}
+
+		_bpbin  = TRUE;
+	}
+
+	if (!_fatin) {		/* access the FAT */
+
+		_dirin = FALSE;
+
+		if (_rdfat(_thefat, _thebpb) < 0) {
+
+			errno = EIO;	/* couldn't read either FAT */
+			return(FAILURE);
+		}
+
+		_fatin  = TRUE;
+		_fatmod = FALSE;
+	}
+/* 
+
+*/
+	if (!_dirin) {		/* access the root directory */
+
+		if (_rdroot(_thedir, _thebpb)) {
+
+			errno = EIO;	/* couldn't read the directory */
+			return(FAILURE);
+		}
+
+		_dirin  = TRUE;
+		_dirmod = FALSE;
+	}
+
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_opfcb(fcp) -- open the FCB pointed to by 'fcp'.  Returns 0 if
+	opened successfully, -1 if an error occurred, with the error code
+	in errno.
+   =============================================================================
+*/
+
+int
+_opfcb(fcp)
+register struct fcb *fcp;
+{
+	int	rc;
+
+	/* check for an already open FCB */
+
+	if (fcp->modefl & FC_OPN) {
+
+		errno = EINVAL;
+		return(IO_ERR);
+	}
+
+	if (_opnvol()) {	/* open the volume */
+
+		_deadio(fcp, errno);
+		return(IO_ERR);
+	}
+
+	/* search the directory for the file */
+
+	if (DE_NULL EQ (_dptr = _dsrch(&fcp->de))) {
+
+		/* file doesn't exist -- see if we should create it */
+
+		if (!(fcp->modefl & FC_CR)) {
+		
+			_deadio(fcp, ENOENT);	/* file nonexistant, not creating one */
+			return(IO_ERR);
+		}
+
+		/* create the file */
+
+		if(rc = _fmake(fcp)) {
+
+			_deadio(fcp, EIO);	/* couldn't create the file */
+			return(IO_ERR);
+		}
+
+/* 
+
+*/
+
+	} else {
+
+		/* file exists -- check for writes to a read-only file */
+
+		if ( (fcp->de.atrib & F_RDONLY) AND
+		     (fcp->modefl & (FC_AP | FC_WR | FC_TR)) ) {
+
+				/* can't append, write or truncate RO files */
+
+				_deadio(fcp, EACCES);
+				return(IO_ERR);
+			}
+
+		/* check for append and not write */
+
+		if ((fcp->modefl & FC_AP) AND !(fcp->modefl & FC_WR)) {
+
+			/* can't append if not open to write */
+
+			_deadio(fcp, EACCES);
+			return(IO_ERR);
+		}
+
+		/* check for create and exclusive with extant file */
+
+		if ((fcp->modefl & FC_CR) AND (fcp->modefl & FC_EX)) {
+
+			/* file exists and open was create-exclusive */
+
+			_deadio(fcp, EEXIST);
+			return(IO_ERR);
+		}
+
+/* 
+
+*/
+
+		/* truncate the file if requested */
+
+		if (fcp->modefl & FC_TR) {
+
+			/* see if we can write */
+
+			if (fcp->modefl & FC_WR) {
+
+				/* truncate the file */
+
+				if (_ftrnc(_dptr)) {
+
+					_deadio(fcp, EIO);	/* truncation failed */
+					return(IO_ERR);
+				}
+
+			} else {
+
+				/* we can't write, so we can't truncate */
+
+				_deadio(fcp, EACCES);
+				return(IO_ERR);
+			}
+		}
+	}
+
+	/* setup the FCB fields */
+
+	memcpy(&fcp->de, _dptr, DENTSIZE);
+	fcp->clsec = 0;
+	fcp->curcls = micons(fcp->de.bclust);
+	fcp->offset = 0;
+	fcp->curlsn = 0L;
+	fcp->curdsn = fcp->de.bclust ? _cl2lsn(_thebpb, fcp->curcls) : 0;
+	fcp->curlen = miconl(fcp->de.flen);
+
+	fcp->asects = ((fcp->curlen / _thebpb->clsizb)
+		+ ((fcp->curlen & (_thebpb->clsizb - 1)) ? 1 : 0))
+		* _thebpb->clsiz;
+
+	fcp->modefl &= ~(FC_EOF | FC_BAD | FC_ERR);
+	fcp->modefl |= FC_OPN;
+
+#if DEBUGIT
+	if (fsdebug)
+		SnapFCB(fcp);
+#endif
+
+	return(IO_OK);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_inifcb(fcp, name, ext, mode) -- initialize FCB pointed to by 'fcp'
+	for file named 'name'.'ext' in mode 'mode'.
+	Returns SUCCESS (0) if ok, FAILURE (-1) if not.
+   =============================================================================
+*/
+
+int
+_inifcb(fcp, name, ext, mode)
+register struct fcb *fcp;
+char *name, *ext;
+int mode;
+{
+	int	fl;
+	register int	i;
+	register char *s1, *s2, c;
+
+	/* clear the FCB */
+
+	memset((char *)fcp, 0, sizeof (struct fcb));
+
+	/* check for valid flags */
+
+	if (mode & ~(O_WRONLY|O_RDWR|O_NDELAY|O_APPEND|O_CREAT|O_TRUNC|O_EXCL|O_RAW))
+		return(FAILURE);
+
+/* 
+
+*/
+	/* check the file name for length */
+
+	fl = TRUE;
+	s1 = name;
+
+	for (i = 0; i < 9; i++)
+		if (*s1++ EQ '\0') {
+
+			fl = FALSE;
+			break;
+		}
+
+	if (fl)
+		return(FAILURE);
+
+	/* check the file name extension for length */
+
+	fl = TRUE;
+	s1 = ext;
+
+	for (i = 0; i <4; i++)
+		if (*s1++ EQ '\0') {
+
+			fl = FALSE;
+			break;
+		}
+
+	if (fl)
+		return(FAILURE);
+
+/* 
+
+*/
+	/* clear the file name and extension in the FCB to blanks */
+
+	memset(fcp->de.fname, ' ', 11);
+
+	/* move the file name into the FCB */
+
+	s1 = fcp->de.fname;
+	s2 = name;
+
+	for (i = 0; i < 8; i++) {
+
+		c = *s2++;
+
+		if ((c EQ '\0') OR (c EQ ' '))
+			break;
+
+		*s1++ = c;
+	}
+
+	/* move the file name extension into the FCB */
+
+	s1 = fcp->de.fext;
+	s2 = ext;
+
+	for (i = 0; i < 3; i++) {
+
+		c = *s2++;
+
+		if ((c EQ '\0') OR (c EQ ' '))
+			break;
+
+		*s1++ = c;
+	}
+
+/* 
+
+*/
+
+	/* set the flags in the FCB and exit */
+
+	if (mode & O_RDONLY)
+		fcp->modefl |= FC_RD;
+
+	if (mode & O_WRONLY)
+		fcp->modefl |= FC_WR;
+
+	if (mode & O_RDWR)
+		fcp->modefl |= FC_RW;
+
+	if (mode & O_NDELAY)
+		fcp->modefl |= FC_NB;
+
+	if (mode & O_APPEND)
+		fcp->modefl |= FC_AP;
+
+	if (mode & O_CREAT)
+		fcp->modefl |= FC_CR;
+
+	if (mode & O_TRUNC)
+		fcp->modefl |= FC_TR;
+
+	if (mode & O_EXCL)
+		fcp->modefl |= FC_EX;
+
+	if (mode & O_RAW)
+		fcp->modefl |= FC_BF;
+
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	ClsFile() -- Closes the file controlled by the FCB pointed to by 'fcp'
+	at the bios level.
+   =============================================================================
+*/
+
+int
+ClsFile(fcp)
+register struct fcb *fcp;
+{
+	register struct dirent *dp;
+
+#if DEBUGIT
+	if (fsdebug) {
+
+		printf("ClsFile($%08lX):  closing file\n", fcp);
+		SnapFCB(fcp);
+	}
+#endif
+
+	if (fcp->modefl & FC_OPN) {	/* is it open ? */
+
+		if (fcp->modefl & (FC_CR | FC_AP | FC_WR)) {	/* writing ? */
+
+			if (dp = _dsrch(&fcp->de)) {	/* locate the dirent */
+
+				/* update the directory entry if it changed */
+
+				if (memcmp(dp, &fcp->de, DENTSIZE)) {
+
+					memcpy(dp, &fcp->de, DENTSIZE);
+					_dirmod = TRUE;
+#if DEBUGIT
+	if (fsdebug) {
+
+		printf("ClsFile():  updated the directory.  FAT:\n");
+		mdump(_thefat, (char *)_thefat+127, _thefat);
+	}
+#endif
+
+				}
+
+/* 
+
+*/
+
+			} else {
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("ClsFile():  ERROR - can't find the directory entry\n");
+#endif
+
+				errno = EIO;	/* can't find the entry */
+				return(FAILURE);
+			}
+		}
+
+#if DEBUGIT
+	if (fsdebug)
+		SnapFCB(fcp);
+#endif
+
+		return(SUCCESS);
+
+	} else {		/* not open */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("ClsFile():  ERROR - file not open\n");
+#endif
+
+		errno = EINVAL;
+		return(FAILURE);
+	}
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_clsvol() -- close the volume
+   =============================================================================
+*/
+
+_clsvol()
+{
+	if (_fatmod) {
+
+		_clsfat();
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_clsvol():  modified FAT written\n");
+#endif
+	}
+
+	if (_dirmod) {
+
+		_clsdir();
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_clsvol():  modified directory written\n");
+#endif
+	}
+
+	_bpbin = FALSE;
+	_fatin = FALSE;
+	_dirin = FALSE;
+}
+
+/*
+   =============================================================================
+	fcbinit() -- initialize an FCB
+   =============================================================================
+*/
+
+short
+fcbinit(name, fcp)
+register char *name;
+register struct fcb *fcp;
+{
+	char	tmpname[9], tmpext[4];
+
+	return(_inifcb(fcp, FilName(name, tmpname), FilExt(name, tmpext), 0));
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	DelFile() -- Deletes the file named by fcb pointed to by 'fcp'.
+   =============================================================================
+*/
+
+int
+DelFile(fcp)
+struct fcb *fcp;
+{
+#if	DEBUGIT
+	if (fsdebug)
+		printf("DelFile($%08.8lX):  deleting [%-.8s].[%-.3s]\n",
+			fcp, fcp->de.fname, fcp->de.fext);
+#endif
+
+	if(_opnvol())			/* open the volume */
+		return(FAILURE);
+
+	if (DE_NULL EQ (_dptr = _dsrch(&fcp->de))) {	/* find the file */
+
+		errno = ENOENT;		/* can't find the file */
+		return(FAILURE);
+	}
+
+	if (_dptr->atrib & F_RDONLY) {
+
+		errno = EACCES;		/* can't delete an R/O file */
+		return(FAILURE);
+	}
+
+	if (_ftrnc(_dptr))		/* truncate the file to free its space  */
+		return(FAILURE);
+
+	_dptr->fname[0] = 0xE5;		/* mark directory entry as free */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("DelFile($%08.8lX):  file [%-.8s].[%-.3s] DELETED\n",
+			fcp, fcp->de.fname, fcp->de.fext);
+#endif
+
+	return(SUCCESS);
+}
Index: libcio/filname.c
===================================================================
--- libcio/filname.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/filname.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,147 @@
+/*
+   =============================================================================
+	filname.c -- file name and extension extractors
+	Version 3 -- 1987-07-09 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#define	TESTER	0		/* define non-zero for test routine */
+
+#include <stddefs.h>
+
+#define	MAX_NAME	8	/* maximum length of a file name */
+#define	MAX_EXT		3	/* maximum length of an extension */
+
+/*
+   =============================================================================
+	FilName(s, p) -- Return a pointer to a string containing the file name
+	found in the string at 's'.  Copy the file name into string 'p'.
+   =============================================================================
+*/
+
+char *
+FilName(s, p)
+register char *s, *p;
+{
+	register char	*tp;
+	register int i;
+
+	tp = p;
+
+	for (i = 0; i < MAX_NAME; i++) {	/* scan the name */
+
+		if (*s) {			/* ... until we hit a '\0' */
+
+			if (*s EQ '.')		/* ... or a '.' */
+				break;
+
+			*p++ = *s++;		/* ... copying as we go */
+
+		} else {			/* stop at '\0' */
+
+			*p = '\0';		/* terminate the string */
+			return(tp);		/* return a pointer to it */
+		}
+	}
+
+	*p = '\0';		/* copied MAX_NAME bytes - that's all folks */
+	return(tp);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	FilExt(s, p) -- Returns a pointer to a copy of the extension of
+	the file name in 's'.  The file name is copied into string 'p' and
+	a pointer to 'p' is returned.
+   =============================================================================
+*/
+
+char *
+FilExt(s, p)
+register char *s, *p;
+{
+	register char c, *tp;
+	register int i;
+
+	tp = p;
+
+	while (c = *s) {		/* scan the string */
+
+		if (c EQ '.') {		/* ... until we hit the dot */
+
+			++s;		/* point past the dot */
+
+			for (i = 0; i < MAX_EXT; i++) {	/* scan the extension ... */
+
+				if (*s) {		/* ... until we hit a '\0' */
+
+					*p++ = *s++;	/* ... copying as we go */
+
+				} else {		/* stop at '\0' */
+
+					*p = '\0';	/* terminate the string */
+					return(tp);	/* return a pointer to it */
+				}
+			}
+
+			*p = '\0';	/* copied MAX_EXT bytes - that's all folks */
+			return(tp);	/* return a pointer to the result */
+				
+		} else {
+
+			++s;		/* advance the pointer */
+		}
+	}
+
+	*p = '\0';	/* terminate the string */
+	return(tp);	/* return a pointer to the result */
+}
+
+/* 
+
+*/
+
+#if	TESTER
+
+char	*fn[] = {		/* test cases */
+
+	"FILE.NAM",
+	"FILE",
+	"FILE.",
+	".NAM",
+	".",
+	"",
+	"fartoolonganame.longextension",
+	"fartoolonganame",
+	"fartoolonganame.",
+	".longextension"
+};
+
+#define	NCASES	((sizeof fn) / (sizeof (char *)))
+
+char	temp1[MAX_NAME+1], temp2[MAX_EXT+1];
+
+fnt(s)		/* test both functions and print the result */
+char *s;
+{
+	printf("[%s] gave [%s] [%s]\r\n",
+		s, FilName(s, temp1), FilExt(s, temp2));
+}
+
+main()
+{
+	int	i;
+
+	/* hand the functions each of the test cases */
+
+	for (i = 0; i < NCASES; i++)
+		fnt(fn[i]);
+
+	exit(0);
+}
+
+#endif
Index: libcio/flread.c
===================================================================
--- libcio/flread.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/flread.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,52 @@
+/*
+   ============================================================================
+	flread.c -- read a long buffer
+	Version 2 -- 1987-07-09 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+#define	CHUNK	32256		/* largest practical sized chunk of data */
+
+/*
+   ============================================================================
+	flread(buff, len, fp) -- Reads 'len' bytes into 'buff' from file 'fp'.
+
+	Returns SUCCESS (0) if OK, EOF (-1) on end of file.
+   ============================================================================
+*/
+
+int
+flread(buff, len, fp)
+register char *buff;
+register long len;
+FILE *fp;
+{
+	register int	ilen;
+
+	while (len > 0L) {
+
+		if (len GE (long)CHUNK) {
+
+			if (1 NE fread(buff, CHUNK, 1, fp))
+				return(EOF);
+
+			buff += (long)CHUNK;
+			len -= (long)CHUNK;
+
+		} else {
+
+			ilen = len;
+
+			if (1 NE fread(buff, ilen, 1, fp))
+				return(EOF);
+
+			len = 0L;
+		}
+	}
+
+	return(SUCCESS);
+}
+
Index: libcio/fopen.c
===================================================================
--- libcio/fopen.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fopen.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,94 @@
+/*
+   =============================================================================
+	fopen.c -- open a stream file for the Buchla 700 C I/O Library
+	Version 4 -- 1987-06-30 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "fcntl.h"
+#include "errno.h"
+#include "stddefs.h"
+
+extern	long lseek();
+
+FILE *
+_opener(name, mode, aflag)
+char *name, *mode;
+int aflag;
+{
+	register FILE *fp;
+	register int plusopt;
+
+	fp = Cbuffs;
+
+	while ( fp->_flags ) {
+
+		if ( ++fp GE (Cbuffs + NSTREAMS))
+			return(NULL);
+	}
+
+	plusopt = mode[1] EQ '+';
+
+	switch (0x007F & *mode) {
+
+	case 'r':	/* read mode */
+		if ((fp->_unit = open(name, (plusopt ? O_RDWR : O_RDONLY)|aflag)) EQ -1)
+			return(NULL);
+		break;
+
+	case 'w':	/* write mode */
+		if ((fp->_unit = open(name, (plusopt ? O_RDWR : O_WRONLY)|aflag|O_CREAT|O_TRUNC)) EQ -1)
+			return(NULL);
+
+		break;
+	
+	case 'a':	/* append mode */
+		if ((fp->_unit = open(name, (plusopt ? O_RDWR : O_WRONLY)|aflag|O_CREAT)) EQ -1)
+			return(NULL);
+
+		if (lseek(fp->_unit, 0L, 2) < 0) {
+
+			close(fp->_unit);
+			return(NULL);		/* couldn't append */
+		}
+
+		break;
+
+	default:
+		errno = EINVAL;
+		return(NULL);
+	}
+
+	fp->_flags  = _BUSY;
+	fp->_buflen = BUFSIZ;
+	fp->_buff   = 0; 
+	fp->_bend   = 0; /* nothing in buffer */
+	fp->_bp     = 0;
+	return(fp);
+}
+
+/* 
+
+*/
+
+FILE *
+fopen(name, mode)
+char *name, *mode;
+{
+	return(_opener(name, mode, 0));
+}
+
+FILE *
+fopena(name, mode)
+char *name, *mode;
+{
+	return(_opener(name, mode, 0));
+}
+
+FILE *
+fopenb(name, mode)
+char *name, *mode;
+{
+	return(_opener(name, mode, O_RAW));
+}
Index: libcio/fprintf.c
===================================================================
--- libcio/fprintf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fprintf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,39 @@
+/*
+   =============================================================================
+	fprintf.c -- fprintf function
+	Version 2 -- 1987-06-26 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+#include "varargs.h"
+
+static FILE *Stream;
+
+extern	int	_dofmt();
+extern	int	aputc();
+
+int
+fprintf(stream, fmt, va_alist)
+FILE *stream;
+char *fmt;
+va_dcl
+{
+	register int count;
+	int fpsub();
+	va_list aptr;
+
+	Stream = stream;
+	va_start(aptr);
+	count = _dofmt(fpsub, fmt, aptr);
+	va_end(aptr);
+	return(count);
+}
+
+static
+int
+fpsub(c)
+{
+	return(aputc(c, Stream));
+}
Index: libcio/fputs.c
===================================================================
--- libcio/fputs.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fputs.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,45 @@
+/*
+   =============================================================================
+	fputs.c -- output a string to a stream
+	Version 3 -- 1987-07-09 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+int
+puts(str)
+register char *str;
+{
+	while (*str)
+		if (putchar(*str++) EQ EOF)
+			return(EOF);
+
+	return(putchar('\n'));
+}
+
+int
+aputc(c,ptr)
+register int c;
+register FILE *ptr;
+{
+	c &= 127;
+
+	if (c EQ '\n')
+		if (putc('\r', ptr) EQ EOF)
+			return(EOF);
+
+	return(putc(c, ptr));
+}
+
+int
+fputs(s,fp)
+register char *s;
+FILE *fp;
+{
+	while ( *s )
+		if (aputc(*s++, fp) EQ EOF)
+			return(EOF);
+	return(0);
+}
Index: libcio/fread.c
===================================================================
--- libcio/fread.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fread.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,40 @@
+/*
+   =============================================================================
+	fread.c -- read a stream file
+	Version 3 -- 1987-06-29 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+/*
+   =============================================================================
+	fread(buffer, size, number, stream) -- read 'number' items of size
+	'size' bytes from file 'stream' into 'buffer'.
+   =============================================================================
+*/
+
+int
+fread(buffer, size, number, stream)
+register char *buffer;
+unsigned size;
+int number;
+FILE *stream;
+{
+	int total;
+	register int c,i;
+
+	for (total = 0; total < number; ++total) {
+
+		for (i = size; i; --i) {
+
+			if ((c = getc(stream)) EQ EOF)
+				return(total);
+
+			*buffer++ = c;
+		}
+	}
+	return(total);
+}
+
Index: libcio/fscanf.c
===================================================================
--- libcio/fscanf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fscanf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,49 @@
+/*
+   =============================================================================
+	fscanf.c -- scan a stream file for input for the portable C I/O Library
+	Version 4 -- 1989-01-16 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+static int scnlast;
+static FILE *scnfp;
+
+static
+int
+gchar(what)
+{
+	if (what EQ 0) {
+
+		if (feof(scnfp))
+			scnlast = EOF;
+		else
+			scnlast = agetc(scnfp);
+	} else
+		scnlast = ungetc(scnlast, scnfp);
+
+	return(scnlast);
+}
+
+int
+scanf(fmt, args)
+char *fmt;
+int *args;
+{
+	scnfp = stdin;
+	scnlast = 0;
+	return(scanfmt(gchar, fmt, &args));
+}
+
+int
+fscanf(fp, fmt, args)
+FILE *fp;
+char *fmt;
+int *args;
+{
+	scnfp = fp;
+	scnlast = 0;
+	return(scanfmt(gchar, fmt, &args));
+}
Index: libcio/fseek.c
===================================================================
--- libcio/fseek.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fseek.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,51 @@
+/*
+   =============================================================================
+	fseek.c -- perform a seek on a stream file
+	Version 4 -- 1987-10-28 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "biosdefs.h"
+#include "io.h"
+#include "stddefs.h"
+
+/*
+   =============================================================================
+	fseek(fp, pos, mode) -- position file 'fp' at 'pos' in mode 'mode'.
+   =============================================================================
+*/
+
+fseek(fp, pos, mode)
+register FILE *fp;
+long pos;
+int mode;
+{
+	register int i, lr;
+	long curpos, lseek();
+
+	if (fp->_flags & _DIRTY) {
+
+		if (flush_(fp, -1))
+			return(EOF);
+
+	} else {
+
+		if (mode EQ 1 AND fp->_bp)
+			pos -= (long)fp->_bend - (long)fp->_bp;
+	}
+
+	fp->_bp = fp->_bend = NULL;
+	fp->_flags &= ~_EOF;
+
+	lr = lseek(fp->_unit, pos, mode);
+
+	if (chantab[fp->_unit].c_arg->modefl & FC_EOF)
+		fp->_flags |= _EOF;
+
+	if (lr < 0)
+		return(EOF);
+
+	return(0);
+}
+
Index: libcio/fsinit.c
===================================================================
--- libcio/fsinit.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fsinit.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,167 @@
+/*
+   ============================================================================
+	fsinit.c -- Initialize file system
+	Version 9 -- 1988-01-31 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#define	_FS_DEF_	/* define so that stdio.h and io.h get things right */
+
+#include "biosdefs.h"
+#include "errno.h"
+#include "io.h"
+#include "stdio.h"
+#include "stddefs.h"
+
+extern	int	_bpbin, _dirin, _fatin, _dirmod, _fatmod;
+
+int	_badfd(), _noper();
+
+char	*Stdbufs;			/* buffer chain pointer */
+
+char	Wrkbuf[BPSEC];			/* sector work buffer */
+
+long	Stdbuf[MAXDFILE][BUFSIZL];	/* standard buffers */
+
+FILE Cbuffs[NSTREAMS];			/* stream file control table */
+
+struct fcb _fcbtab[MAXDFILE];		/* fcb table */
+
+struct channel  chantab[MAXCHAN];	/* channel table:  relates fd's to devices */
+
+#if	TBUFFER
+
+/* WARNING:  this ONLY works for 512 byte sectors, 9 sectors per track */
+
+short	_b_tbuf[9][256];	/* the track buffer */
+
+short	_b_trak;		/* current track */
+short	_b_side;		/* current side */
+short	_b_sect;		/* current sector */
+short	_b_tsec;		/* current base sector of current track */
+
+#endif
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	_badfd() -- set "bad fd" error
+   ============================================================================
+*/
+
+int
+_badfd()
+{
+	errno = EBADF;		/* set bad fd code */
+	return(FAILURE);	/* return with an error indication */
+}
+
+/*
+   ============================================================================
+	_noper() -- null return with no error condition
+   ============================================================================
+*/
+
+int
+_noper()
+{
+	return(SUCCESS);	/* return with a non-error indication */
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	InitCH() -- Initialize chantab structure entry
+   ============================================================================
+*/
+
+InitCH(cp, rdi, wri, ioi, ski, cfp, charg)
+register struct channel *cp;
+char rdi, wri, ioi, ski;
+int (*cfp)();
+io_arg charg;
+{
+	cp->c_read  = rdi;
+	cp->c_write = wri;
+	cp->c_ioctl = ioi;
+	cp->c_seek  = ski;
+	cp->c_close = cfp;
+	cp->c_arg   = charg;
+}
+
+/*
+   ============================================================================
+	Init_CB() -- Initialize Cbuff structure entry
+   ============================================================================
+*/
+
+Init_CB(fp, flags, unit, bufad, bufsize)
+register FILE *fp;
+char unit, flags;
+long *bufad;
+int bufsize;
+{
+	fp->_bp     = (char *)0L;
+	fp->_bend   = (char *)0L;
+	fp->_buff   = (char *)bufad;
+	fp->_flags  = flags;
+	fp->_unit   = unit;
+	fp->_bytbuf = 0;
+	fp->_buflen = bufsize;
+};
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	InitFS() -- Initialize file system
+   ============================================================================
+*/
+
+InitFS()
+{
+	register int i;
+
+	memset(_fcbtab, 0, sizeof _fcbtab);		/* clear fcb table */
+	memsetw(Stdbuf, 0, sizeof Stdbuf / 2);		/* clear buffers */
+
+	Init_CB(stdin,  _BUSY, 0, (char *)0L, BUFSIZ);	/* stdin */
+	Init_CB(stdout, _BUSY, 1, (char *)0L, 1);	/* stdout */ 
+	Init_CB(stderr, _BUSY, 2, (char *)0L, 1);	/* stderr */
+
+	for (i = 3; i < NSTREAMS; i++)
+		Init_CB(&Cbuffs[i], 0, 0, (char *)0L, 0);
+
+	Stdbuf[0][0] = 0L;		/* initialize the buffer list */
+
+	for (i = 1; i < MAXDFILE; i++)
+		Stdbuf[i][0] = (long)Stdbuf[i-1];
+
+	Stdbufs = Stdbuf[MAXDFILE-1];
+
+	InitCH(&chantab[0], 2, 0, 1, 0, _noper, (io_arg)CON_DEV );	/*  0 - stdin  */
+	InitCH(&chantab[1], 0, 2, 1, 0, _noper, (io_arg)CON_DEV );	/*  1 - stdout */
+	InitCH(&chantab[2], 0, 2, 1, 0, _noper, (io_arg)CON_DEV );	/*  2 - stderr */
+
+	for (i = 3; i < MAXCHAN; i++)	/*  3..MAXCHAN-1 - not preassigned */
+		InitCH(&chantab[i], 0, 0, 0, 0, _badfd, (io_arg)0L );
+
+	_bpbin  = FALSE;	/* BPB isn't in memory */
+	_dirin  = FALSE;	/* directory isn't in memory */
+	_fatin  = FALSE;	/* FAT isn't in memory */
+	_fatmod = FALSE;	/* FAT hasn't been changed */
+	_dirmod = FALSE;	/* directory hasn't been changed */
+
+#if	TBUFFER
+	_b_trak = -1;		/* no track in the buffer */
+	_b_side = -1;		/* ... */
+#endif
+}
Index: libcio/fsize.c
===================================================================
--- libcio/fsize.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fsize.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,98 @@
+/*
+   =============================================================================
+	fsize.c -- file size and disk capacity functions
+	Version 1 -- 1987-10-29 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "biosdefs.h"
+#include "io.h"
+#include "stddefs.h"
+
+extern	short	_gtcl12(), _opnvol(), _filecl();
+
+extern	unsigned _thefat[];
+
+extern	struct	bpb	*_thebpb;
+
+/*
+   =============================================================================
+	fsize() -- return the current size of an open stream file
+
+		how = 0: in bytes, 1: in allocated clusters
+   =============================================================================
+*/
+
+long
+fsize(fp, how)
+FILE *fp;
+short how;
+{
+	register struct channel *chp;
+	register struct fcb *fcp;
+
+	if (fp EQ (FILE *)0L)
+		return(-1L);
+
+	if (fp->_flags & _BUSY) {
+
+		chp = &chantab[fp->_unit];
+
+		if (chp->c_close NE _filecl)
+			return(-1L);
+
+		fcp = chp->c_arg;
+
+		if (fcp->modefl & FC_OPN) {
+
+			if (how)
+				return(fcp->asects);
+			else
+				return(fcp->curlen);
+
+		} else
+			return(-1L);
+
+	} else
+		return(-1L);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	dspace() -- return disk capacity or usage
+
+		which = 0: capcity, 1: usage
+   =============================================================================
+*/
+
+short
+dspace(which)
+short which;
+{
+	register short maxcl, clcount, nc;
+
+	if (_opnvol())
+		return(-1L);
+
+	maxcl = _thebpb->numcl;
+
+	if (which) {
+
+		clcount = 0;
+
+		for (nc = 2; nc < maxcl; nc++)
+			if (0 EQ _gtcl12(_thefat, nc))
+				++clcount;
+
+		return(clcount);
+
+	} else {
+
+		return(maxcl);
+	}
+}
Index: libcio/fstubs.c
===================================================================
--- libcio/fstubs.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fstubs.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,49 @@
+/*
+   =============================================================================
+	fstubs.c -- stubs for testing with
+	Version 13 -- 1987-11-13 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+#include "errno.h"
+#include "stdio.h"
+#include "io.h"
+#include "stddefs.h"
+
+/*
+   =============================================================================
+	readbuf() -- Reads an edited string from 'dev' into 'buf'
+	in {MS|GEM}DOS buffer format.
+
+	Buffer format:
+
+		buf[0] = buffer length, buf[1] = number of bytes read,
+		buf[2]..buf[buf[0]-1 = data area
+
+	Editing characters:
+
+		CR, LF	End the line
+		BS, DEL	Erase last character
+		^U,^X	Cancel (erase) entire line
+		^R	Retype line
+		^C	Terminate the process
+		^Z	End of file / end of line
+
+	Returns:
+	      Value     stddef	Meaning
+	      -----     ------- --------------------------------------------
+		1		Terminate process (^C entered)
+		0	SUCCESS	Line available in buffer  (CR or LF entered)
+	       -1	EOF	End of file (^Z entered)
+   =============================================================================
+*/
+
+int
+readbuf(dev, buf)
+int dev;
+char *buf;
+{
+	xtrap15();
+	return(1);
+}
Index: libcio/ftell.c
===================================================================
--- libcio/ftell.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/ftell.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,96 @@
+/*
+   =============================================================================
+	ftell.c -- return current file position
+	Version 7 -- 1987-10-28 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "biosdefs.h"
+#include "stdio.h"
+#include "io.h"
+#include "stddefs.h"
+
+#if	DEBUGIT
+extern	short	fsdebug;
+#endif
+
+extern	int	_filecl();
+
+/*
+   =============================================================================
+	ftell(fp) -- return the current position of file 'fp'.
+   =============================================================================
+*/
+
+long
+ftell(fp)
+register FILE *fp;
+{
+	register struct fcb *fcp;
+	register struct channel *chp;
+	register long dpos, pos, diff;
+
+	if (fp EQ (FILE *)0L) {		/* see if we point at a FILE */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("ftell($%08.8lX):  ERROR - null FILE pointer\n", fp);
+#endif
+
+		return(0L);
+	}
+
+	if (!fp->_flags & _BUSY) {	/* see if it's open */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("ftell($%08.8lX):  ERROR - FILE not open\n", fp);
+#endif
+
+		return(0L);
+	}
+
+	chp = &chantab[fp->_unit];	/* point at the channel */
+
+	if (chp->c_close NE _filecl) {	/* see if it's seekable */
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("ftell($%08.8lX):  ERROR - FILE device not seekable\n",
+			fp);
+#endif
+
+		return(0L);
+	}
+
+	fcp = chp->c_arg;		/* point at the FCB */
+
+	dpos = fcp->offset + (fcp->curlsn << FILESHFT);
+
+	if (fp->_flags & _DIRTY)	/* adjust for the buffering */
+		pos = dpos + (diff = ((long)fp->_bp - (long)fp->_buff));
+	else if (fp->_bp)
+		pos = dpos - (diff = ((long)fp->_bend - (long)fp->_bp));
+	else
+		pos = dpos;
+
+#if	DEBUGIT
+	if (fsdebug) {
+
+		printf("ftell($%08.8lX):  flags=$%04.4X, buff=$%08.8lX, bp=$%08.8lX, bend=$%08.8lX\n",
+			fp, fp->_flags, fp->_buff, fp->_bp, fp->_bend);
+	printf("ftell($%08.8lX):  fcp=$%08.8lX, pos=%ld, dpos=%ld, diff=%ld\n",
+			fp, fcp, pos, dpos, diff);
+		printf("ftell($%08.8lX):  curlsn=%ld, offset=%u\n",
+			fp, fcp->curlsn, fcp->offset);
+
+		if ((fp->_flags & _DIRTY) AND (fp->_bp EQ NULL))
+			printf("ftell($%08.8lX):  ERROR - file is DIRTY and bp is NULL\n",
+				fp);
+	}
+#endif
+
+	return(pos);
+}
Index: libcio/fwrite.c
===================================================================
--- libcio/fwrite.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/fwrite.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,43 @@
+/*
+   =============================================================================
+	fwrite.c -- write a stream file
+	Version 3 -- 1987-07-09 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+/*
+   =============================================================================
+	fwrite(buffer, size, number, stream) -- write 'number' items of sixe
+	'size' bytes from 'buffer' onto 'stream'.  Returns the number of items
+	written.  If 'number' or 'size' is negative, nothing is written, and
+	0 is returned.  EOF may cause the last item written to be imcomplete.
+	Check with feof() to detect an EOF condition.  Use ferror() to check
+	for error conditions.
+   =============================================================================
+*/
+
+int
+fwrite(buffer, size, number, stream)
+register char *buffer;
+register int size, number;
+register FILE *stream;
+{
+	register int i, j;
+
+	if (size < 0)		/* check size for validity */
+		return(0);
+
+	if (number < 0)		/* check number for validity */
+		return(0);
+
+	for (i = 0; i < number; ++i)
+		for (j = 0; j < size; ++j)
+			if (putc(*buffer++, stream) EQ EOF)
+				return(i);
+
+	return(number);
+}
+
Index: libcio/getbuff.c
===================================================================
--- libcio/getbuff.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/getbuff.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,37 @@
+/*
+   ============================================================================
+	getbuff.c -- Get a buffer for a file for the Buchla 700 C I/O Library
+	Version 4 -- 1987-06-24 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+getbuff(ptr)
+register FILE *ptr;
+{
+	char *buffer;
+
+	if (ptr->_buflen EQ 1) {	/* see if we want the small buffer */
+
+		ptr->_buff = &ptr->_bytbuf;
+		return;
+	}
+
+	if (Stdbufs) {		/* see if we have any standard buffers left */
+
+		buffer = (char *)Stdbufs;
+		Stdbufs = *(long **)Stdbufs;
+
+	} else {		/* ... if not, use the small one */
+
+		ptr->_buff = &ptr->_bytbuf;
+		ptr->_buflen = 1;
+		return;
+	}
+
+	ptr->_flags |= _ALLBUF;		/* say we allocated a standard buffer */
+	ptr->_buff = buffer;
+	return;
+}
Index: libcio/getc.c
===================================================================
--- libcio/getc.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/getc.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,37 @@
+/*
+   ============================================================================
+	getc.c -- get a character from a stream file
+	Version 3 -- 1987-09-22 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+int
+getc(ptr)
+register FILE *ptr;
+{
+	register int len;
+
+	if (ptr->_bp >= ptr->_bend) {		/* see if the buffer is empty */
+
+		if (ptr->_flags & _EOF)		/* check EOF status */
+			return(EOF);
+
+		ptr->_flags &= ~_DIRTY;		/* reset the dirty buffer bit */
+
+		if (ptr->_buff EQ NULL)		/* get a buffer if none exists */
+			getbuff(ptr);
+
+		if ((len = read(ptr->_unit, ptr->_buff, ptr->_buflen)) LE 0) {
+
+			ptr->_flags |= ((len EQ 0) ? _EOF : _IOERR);
+			return(EOF);
+		}
+
+		ptr->_bend = (ptr->_bp = ptr->_buff) + len;
+	}
+
+	return(*ptr->_bp++ & 0xFF);
+}
Index: libcio/getl.c
===================================================================
--- libcio/getl.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/getl.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,36 @@
+/*
+   =============================================================================
+	getl.c -- get a 68000 long word from a stream file
+	Version 2 -- 1987-10-15 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+
+extern	int	fgetc();
+
+/*
+   =============================================================================
+	getl(stream) -- get a long word from 'stream'
+
+	Reads a long from 'stream' in Motorola 68000 byte order.
+	No special alignment is assumed in the file.
+   =============================================================================
+*/
+
+long
+getl(stream)
+register FILE *stream;
+{
+	long temp;
+	register char *t;
+
+	t = &temp;
+
+	*t++ = fgetc(stream);
+	*t++ = fgetc(stream);
+	*t++ = fgetc(stream);
+	*t = fgetc(stream);
+
+	return(temp);
+}
Index: libcio/getw.c
===================================================================
--- libcio/getw.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/getw.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,34 @@
+/*
+   =============================================================================
+	getw.c -- get a 68000 word from a stream file
+	Version 2 -- 1987-10-15 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+
+extern	int	fgetc();
+
+/*
+   =============================================================================
+	getw(stream) -- get a word from 'stream'
+
+	Reads a word from 'stream' in Motorola 68000 byte order.
+	No special alignment is assumed in the file.
+   =============================================================================
+*/
+
+int
+getw(stream)
+register FILE *stream;
+{
+	int temp;
+	register char *t;
+
+	t = &temp;
+
+	*t++ = fgetc(stream);
+	*t = fgetc(stream);
+
+	return(temp);
+}
Index: libcio/lseek.c
===================================================================
--- libcio/lseek.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/lseek.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,123 @@
+/*
+   =============================================================================
+	lseek.c -- position a file to a specified byte location
+	Version 7 -- 1987-10-28 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "io.h"
+#include "biosdefs.h"
+#include "errno.h"
+#include "stddefs.h"
+
+extern	int	_seek();
+
+#if	DEBUGIT
+extern	short	fsdebug;
+#endif
+
+long
+lseek(fd, pos, how)
+int fd;
+register long pos;
+int how;
+{
+	register struct fcb *fp;
+
+	if ((fd < 0) OR (fd > MAXCHAN)) {
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("lseek(%d):  bad file index\n", fd);
+#endif
+
+		errno = EBADF;		/* file number bad */
+		return(-1L);
+	}
+
+	if (chantab[fd].c_seek EQ 0) {
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("lseek(%d):  device not seekable\n", fd);
+#endif
+
+		errno = EINVAL;		/* device can't seek */
+		return(-1L);
+	}
+
+	fp = chantab[fd].c_arg;		/* get fcb pointer from channel table */
+
+	switch (how) {			/* dispatch off of seek type */
+
+	case 2:				/* relative to end of file */
+		pos += fp->curlen;
+		break;
+
+	case 1:				/* relative to current position */
+		pos += fp->offset + (fp->curlsn << FILESHFT);
+
+	case 0:				/* relative to start of file */
+		break;
+
+	default:
+		errno = EINVAL;		/* invalid seek type */
+		return(-1L);
+	}
+/* 
+
+*/
+	if (pos < 0) {				/* trap seeks before BOF */
+
+		fp->offset = 0;
+		fp->curlsn = 0;
+		fp->modefl |= FC_ERR;
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("lseek(%d):  seek (%ld) is before BOF\n", fd, pos);
+#endif
+
+		errno = EINVAL;
+		return(-1L);
+
+	} else if (pos > fp->curlen) {		/* trap seeks past EOF */
+
+		fp->offset = fp->curlen & (BPSEC -1);
+		fp->curlsn = fp->curlen >> FILESHFT;
+		fp->modefl |= FC_ERR;
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("lseek(%d):  seek (%ld) is after EOF (%ld)\n",
+			fd, pos, fp->curlen);
+#endif
+
+		errno = EINVAL;
+		return(-1L);
+	}
+
+	fp->offset = pos & ((long)BPSEC - 1);	/* calculate sector offset */
+	fp->curlsn = pos >> FILESHFT;		/* calculate logical sector */
+
+	if (_seek(fp) < 0) {			/* position to the physical sector */
+
+		fp->modefl |= FC_ERR;		/* couldn't seek */
+		errno = EIO;
+		return(-1L);
+	}
+
+	if (pos EQ fp->curlen)
+		fp->modefl |= FC_EOF;
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("lseek():  pos=%d, curlsn=%ld, curdsn=%ld, offset=%u\n",
+			pos, fp->curlsn, fp->curdsn, fp->offset);
+#endif
+
+	return(pos);				/* return current position */
+}
+
Index: libcio/open.c
===================================================================
--- libcio/open.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/open.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,268 @@
+/*
+   =============================================================================
+	open.c -- open a file for the Buchla 700 C I/O library functions
+	Version 11 -- 1988-01-31 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+#include "errno.h"
+#include "fcntl.h"
+#include "io.h"
+#include "stddefs.h"
+
+extern	int	_badfd(), _noper();
+extern	int	_inifcb(), _opfcb();
+
+extern	char	*FilName(), *FilExt();
+
+int	_fileop(), _filecl();
+
+static struct device condev  = { 2, 2, 1, 0, _noper  };
+static struct device filedev = { 1, 1, 0, 1, _fileop };
+
+extern	struct fcb _fcbtab[];
+
+/*
+   =============================================================================
+	device table:  contains names and pointers to device control structures
+   =============================================================================
+*/
+
+static struct devtabl devtabl[] = {
+
+	{ "con:", &condev,  2 },	/* console device */
+	{ "CON:", &condev,  2 },
+
+	{      0, &filedev, 0 }		/* this MUST be the last entry */
+};
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	open(name, flag, mode) -- Opens file 'name' with flags 'flag'
+	and access mode 'mode'.  File will be ASCII unless opened with O_RAW.
+	Returns a file descriptor (small positive integer) if successful, or
+	FAILURE (-1) if an error occurred.
+   =============================================================================
+*/
+
+int
+open(name, flag, mode)
+char *name;
+int flag, mode;
+{
+	register struct devtabl	*dp;
+	register struct channel	*chp;
+	register struct device	*dev;
+	int	fd, mdmask;
+
+	/* search for a free channel */
+
+	for (chp = chantab, fd = 0 ; fd < MAXCHAN ; ++chp, ++fd)
+		if (chp->c_close EQ _badfd)
+			goto fndchan;
+
+	errno = EMFILE;		/* no channels available */
+	return(FAILURE);
+
+/* 
+
+*/
+
+fndchan:	/* found a channel to use */
+
+	for (dp = devtabl; dp->d_name; ++dp)	 /* search for the device */
+		if (strcmp(dp->d_name, name) EQ 0)
+			break;
+
+	dev = dp->d_dev;
+	mdmask = (flag & 3) + 1;
+
+	if (mdmask & 1) {	/* see if device is readable */
+
+		if ((chp->c_read = dev->d_read) EQ 0) {
+
+			errno = EACCES;		/* can't read */
+			return(FAILURE);
+		}
+	}
+
+	if (mdmask & 2) {	/* see if device is writeable */
+
+		if ((chp->c_write = dev->d_write) EQ 0) {
+
+			errno = EACCES;		/* can't write */
+			return(FAILURE);
+		}
+	}
+
+	/* setup the channel table entries */
+
+	chp->c_arg   = dp->d_arg;
+	chp->c_ioctl = dev->d_ioctl;
+	chp->c_seek  = dev->d_seek;
+	chp->c_close = _noper;
+
+	if ((*dev->d_open)(name, flag, mode, chp, dp) < 0) {	/* open */
+
+		chp->c_close = _badfd;	/* couldn't open for some reason */
+		return(FAILURE);
+	}
+
+	return(fd);
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	opena(name, flag, mode) -- Opens ASCII file 'name' with flags 'flag'
+	and access mode 'mode'.  Newline translation will be done.
+	Returns a file descriptor (small positive integer) if successful, or
+	FAILURE (-1) if an error occurred.
+   =============================================================================
+*/
+
+int
+opena(name, flag, mode)
+char *name;
+int flag, mode;
+{
+	return(open(name, flag, mode));
+}
+
+/*
+   =============================================================================
+	openb(name, flag, mode) -- Opens binary file 'name' with flags 'flag'
+	and access mode 'mode'.  No newline translation is done.
+	Returns a file descriptor (small positive integer) if successful, or
+	FAILURE (-1) if an error occurred.
+   =============================================================================
+*/
+
+int
+openb(name, flag, mode)
+char *name;
+int flag, mode;
+{
+	return(open(name, flag|O_RAW, mode));
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	creat(name, mode) -- Creates file 'name' with access mode 'mode'.
+	The created file is initially open for writing only.  The file
+	will be ASCII unless mode contains O_RAW.
+	Returns a file descriptor (small positive integer) if successful, or
+	FAILURE (-1) if an error occurred.
+   =============================================================================
+*/
+
+int
+creat(name, mode)
+char *name;
+int mode;
+{
+	return(open(name, O_WRONLY|O_TRUNC|O_CREAT, mode));
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	creata(name, mode) -- Creates ASCII file 'name' with access mode 'mode'.
+	The created file is initially open for writing only.
+	Files created with creata() do newline translations.
+	Returns a file descriptor (small positive integer) if successful, or
+	FAILURE (-1) if an error occurred.
+   =============================================================================
+*/
+
+int
+creata(name, mode)
+char *name;
+int mode;
+{
+	return(open(name, O_WRONLY|O_TRUNC|O_CREAT, mode));
+}
+
+/*
+   =============================================================================
+	creatb(name, mode) -- create binary file 'name' with access mode 'mode'.
+	The created file is initially open for writing only.
+	Files created with creatb don't do newline translations.
+	Returns a file descriptor (small positive integer) if successful, or
+	FAILURE (-1) if an error occurred.
+   =============================================================================
+*/
+
+int
+creatb(name, mode)
+char *name;
+int mode;
+{
+	return(creat(name, O_WRONLY|O_TRUNC|O_CREAT|O_RAW, mode));
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_fileop(name, flag, mode, chp, dp) -- Opens disk file 'name' with
+	flags 'flag' in mode 'mode' with channel pointer 'chp' and
+	device pointer 'dp'.  Returns SUCCESS (0) or FAILURE (-1).
+   =============================================================================
+*/
+
+int
+_fileop(name, flag, mode, chp, dp)
+char *name;
+int flag, mode;
+struct channel *chp;
+struct devtabl *dp;
+{
+	register struct fcb *fp;
+	char	tmpname[9], tmpext[4];
+
+	/* search for an available fcb entry */
+
+	for (fp = _fcbtab; fp < (_fcbtab + MAXDFILE); ++fp)
+		if (fp->modefl EQ 0)
+			goto havefcb;
+
+	errno = ENFILE;		/* no fcb space available for file */
+	return (FAILURE);
+
+havefcb:
+
+	/* setup the initial fcb */
+
+	if (_inifcb(fp, FilName(name, tmpname), FilExt(name, tmpext), flag)) {
+
+		errno = EINVAL;		/* bad file name or flags */
+		return(FAILURE);
+	}
+
+	if (_opfcb(fp))			/* open the file */
+		return(FAILURE);
+
+	chp->c_arg   = fp;		/* allocate the channel */
+	chp->c_close = _filecl;
+
+	return(SUCCESS);
+}
+
Index: libcio/posit.c
===================================================================
--- libcio/posit.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/posit.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,55 @@
+/*
+   =============================================================================
+	posit.c -- position a file to a specific relative sector
+	Version 4 -- 1987-06-29 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "biosdefs.h"
+#include "io.h"
+#include "errno.h"
+#include "stddefs.h"
+
+extern	int	_seek();
+
+/*
+   =============================================================================
+	posit(fd, pos) -- position file 'fd' at sector 'pos'.
+   =============================================================================
+*/
+
+int
+posit(fd, pos)
+int fd;
+unsigned pos;
+{
+	register struct fcb *fp;
+
+	if ((fd < 0) OR (fd > MAXCHAN)) {
+
+		errno = EBADF;
+		return(FAILURE);
+	}
+
+	fp = chantab[fd].c_arg;
+
+	if ((chantab[fd].c_seek EQ 0)
+	    OR ((pos << FILESHFT) > fp->curlen)) {
+
+		errno = EINVAL;
+		fp->modefl |= FC_ERR;
+		return(FAILURE);
+	}
+
+	fp->curlsn = pos;
+	fp->offset = 0;
+
+	if (_seek(fp) < 0) {
+
+		errno = EIO;
+		fp->modefl |= FC_ERR;
+		return(FAILURE);
+	}
+
+	return(SUCCESS);
+}
Index: libcio/ptcl12.s
===================================================================
--- libcio/ptcl12.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/ptcl12.s	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,49 @@
+* ------------------------------------------------------------------------------
+* ptcl12.s -- store a cluster entry into the FAT
+* Version 2 -- 1987-10-27 -- D.N. Lynx Crowe
+* ------------------------------------------------------------------------------
+		.text
+		.xdef	__ptcl12
+*
+CL		.equ	12
+VAL		.equ	14
+CLA		.equ	d7
+CLP		.equ	d6
+CLT		.equ	d5
+FAT		.equ	a5
+*
+__ptcl12:	link	A6,#0
+		movem.l	CLT-CLA/FAT-FAT,-(sp)
+		move.l	8(A6),FAT
+		move.w	CL(A6),CLA
+		lsr.w	CLA
+		add.w	CL(A6),CLA
+		move.b	1(FAT,CLA.W),CLP
+		lsl.w	#8,CLP
+		move.b	0(FAT,CLA.W),CLP
+		btst	#0,CL+1(A6)
+		beq	L2
+*
+		move.w	CLP,CLT
+		and.w	#$000F,CLT
+		move.w	VAL(A6),D0
+		lsl.w	#4,D0
+		or.w	D0,CLT
+		bra	L3
+*
+L2:		move.w	CLP,CLT
+		and.w	#$F000,CLT
+		move.w	VAL(A6),D0
+		and.w	#$0FFF,D0
+		or.w	D0,CLT
+*
+L3:		move.b	CLT,0(FAT,CLA.W)
+		move.w	CLT,D0
+		lsr.w	#8,D0
+		move.b	D0,1(FAT,CLA.W)
+*
+L1:		movem.l	(sp)+,CLT-CLA/FAT-FAT
+		unlk	A6
+		rts
+*
+		.end
Index: libcio/putc.c
===================================================================
--- libcio/putc.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/putc.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,180 @@
+/*
+   ============================================================================
+	putc.c -- stream file output and close functions
+	Version 7 -- 1987-10-19 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+extern	int	write(), getbuff(), close();
+
+extern int (*_clsall)();
+
+static int (*cls_rtn)();
+
+int	_ClFlag;
+
+int	fclose();
+
+/*
+   ============================================================================
+	closall() -- close all files at exit
+   ============================================================================
+*/
+
+static
+closall()
+{
+	register FILE *fp;
+
+	for (fp = Cbuffs; fp < (Cbuffs + NSTREAMS); )	/* close each file */
+		fclose(fp++);
+
+	(*cls_rtn)();		/* do final closeout */
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	flush_() -- do the dirty work of flushing a file
+   ============================================================================
+*/
+
+int
+flush_(ptr, data)
+register FILE *ptr;
+int data;
+{
+	register int size;
+
+	if (_ClFlag EQ 0) {
+
+		cls_rtn = _clsall;
+		_clsall = closall;
+		_ClFlag = 1;
+	}
+
+	if (ptr->_flags & _DIRTY) {	/* something in the buffer ? */
+
+		size = (int)((long)ptr->_bp - (long)ptr->_buff);
+
+		if (write(ptr->_unit, ptr->_buff, size) EQ -1) {
+
+ioerr:
+			ptr->_flags |= _IOERR;
+			return(EOF);
+		}
+	}
+
+	if (data EQ -1) {	/* just flushing, not adding data */
+
+		ptr->_flags &= ~_DIRTY;
+		ptr->_bend = ptr->_bp = NULL;
+		return(0);
+	}
+
+	if (ptr->_buff EQ NULL)		/* get a buffer if we don't have one */
+		getbuff(ptr);
+
+	if (ptr->_buflen EQ 1) {	/* unbuffered I/O */
+
+		if (write(ptr->_unit, &data, 1) EQ -1)
+			goto ioerr;
+
+		return(data);
+	}
+
+	ptr->_bp = ptr->_buff;
+	ptr->_bend = ptr->_buff + ptr->_buflen;
+	ptr->_flags |= _DIRTY;
+
+	return((*ptr->_bp++ = data) & 0x00FF);
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	fflush() -- flush a stream file
+   ============================================================================
+*/
+
+int
+fflush(ptr)
+FILE *ptr;
+{
+	return(flush_(ptr, -1));
+}
+
+/*
+   ============================================================================
+	fclose() -- close a stream file
+   ============================================================================
+*/
+
+int
+fclose(ptr)
+register FILE *ptr;
+{
+	int err;
+
+	err = 0;
+
+	if (ptr->_flags) {
+
+		if (ptr->_flags & _DIRTY)	/* if modifed, flush buffer */
+			err = flush_(ptr, -1);
+
+		err |= close(ptr->_unit);
+
+		if (ptr->_flags & _ALLBUF) {	/* deallocate standard buffer */
+
+			*(long **)ptr->_buff = Stdbufs;
+			Stdbufs = (long *)ptr->_buff;
+		}
+	}
+
+	ptr->_flags = 0;
+	return(err);
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	putc() -- write a character on a file
+   ============================================================================
+*/
+
+int
+putc(c, ptr)
+int c;
+register FILE *ptr;
+{
+	if (ptr->_bp GE ptr->_bend)
+		return(flush_(ptr, c & 0xFF));
+
+	return((*ptr->_bp++ = c) & 0xFF);
+}
+
+/*
+   ============================================================================
+	puterr() -- write a character to stderr
+   ============================================================================
+*/
+
+int
+puterr(c)
+{
+	return(putc(c, stderr));
+}
+
Index: libcio/putl.c
===================================================================
--- libcio/putl.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/putl.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,27 @@
+/*
+   ============================================================================
+	putl.c -- put a Motorola 68000 long word onto a stream file
+	Version 2 -- 1987-10-15 -- D.N. Lynx Crowe
+
+	WARNING:  This fails if the stream is ASCII.
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+putl(w, stream)
+register long w;
+register FILE *stream;
+{
+	if (putc(((w >> 24) & 0xFF), stream) < 0 ) 
+		return;
+
+	if (putc(((w >> 16) & 0xFF), stream) < 0 ) 
+		return;
+
+	if (putc(((w >> 8) & 0xFF), stream) < 0 ) 
+		return;
+
+	putc((w & 0xFF), stream);
+}
Index: libcio/putw.c
===================================================================
--- libcio/putw.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/putw.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,21 @@
+/*
+   ============================================================================
+	putw.c -- put a word onto a stream file
+	Version 3 -- 1987-10-15 -- D.N. Lynx Crowe
+
+	WARNING:  This fails if the stream is ASCII.
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+putw(w, stream)
+register unsigned w;
+FILE *stream;
+{
+	if (putc(((w >> 8) & 0xFF), stream) < 0 ) 
+		return;
+
+	putc((w & 0xFF), stream);
+}
Index: libcio/read.c
===================================================================
--- libcio/read.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/read.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,184 @@
+/*
+   =============================================================================
+	read.c -- file read functions for the C I/O Library
+	Version 9 -- 1987-10-28 -- D.N. Lynx Crowe
+
+	int
+	read(fd, buff, len)
+	char *buff;
+
+		Reads 'len' bytes from file 'fd' into 'buff'.
+		Returns FAILURE (-1) for errors, number of bytes read
+		if successful.
+
+	int
+	_getsec(fp, buf, len)
+	register struct fcb *fp;
+	char *buf;
+	unsigned len;
+
+		Gets 'len' bytes into 'buf' from file 'fp'.
+		Returns FAILURE (-1) for errors, SUCCESS (0) if successful.
+
+	int
+	_filerd(fp, buffer, len)
+	register struct fcb *fp;
+	char *buffer;
+	unsigned len;
+
+		Reads 'len' bytes into 'buffer' from 'fp'.
+		Returns FAILURE (-1) for errors, number of bytes read
+		if successful.
+
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "biosdefs.h"
+#include "io.h"
+#include "errno.h"
+#include "fcntl.h"
+#include "stddefs.h"
+
+#if	DEBUGIT
+extern	short	fsdebug;
+#endif
+
+extern	int	_badfd(), _conin(), _seek();
+
+extern	char	*memcpy();
+
+int	_filerd();
+
+static int (*t_read[])() = {
+
+	_badfd,		/* 0 - invalid type */
+	_filerd,	/* 1 - disk file read */
+	_conin		/* 2 - console read */
+};
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	read(fd, buff, len) -- Reads 'len' bytes from file 'fd' into 'buff'.
+	Returns FAILURE (-1) for errors, number of bytes read if successful.
+   =============================================================================
+*/
+
+int
+read(fd, buff, len)
+int fd;
+char *buff;
+unsigned len;
+{
+	register struct channel *chp;
+
+	if (fd < 0 OR fd > MAXCHAN) {	/* check fd range */
+
+		errno = EBADF;	/* bad fd */
+		return(FAILURE);
+	}
+
+	chp = &chantab[fd];	/* point at the channel table */
+	return((*t_read[chp->c_read])(chp->c_arg, buff, len));	/* do the read */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_getsec(fp, buf, len) -- Gets 'len' bytes into 'buf' from file 'fp'.
+	Returns FAILURE (-1) for errors, SUCCESS (0) if successful.
+   =============================================================================
+*/
+
+int
+_getsec(fp, buf, len)
+register struct fcb *fp;
+char *buf;
+unsigned len;
+{
+	if ((errno = ReadRN(fp, Wrkbuf)) NE 0)	/* get current sector */
+		return(FAILURE);
+
+	memcpy(buf, Wrkbuf + fp->offset, len);	/* move what we need */
+
+	if ((fp->offset = (fp->offset + len) & (BPSEC - 1)) EQ 0) {
+
+		++fp->curlsn;			/* advance the sector number */
+
+		if (_seek(fp) < 0)		/* seek to the next sector */
+			return(FAILURE);
+	}
+
+	return(SUCCESS);			/* return:  all bytes read */
+}
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	_filerd(fp, buffer, len) -- Reads 'len' bytes into 'buffer' from 'fp'.
+	Returns FAILURE (-1) for errors, number of bytes read if successful.
+   =============================================================================
+*/
+
+int
+_filerd(fp, buffer, len)
+register struct fcb *fp;
+char *buffer;
+unsigned len;
+{
+	register unsigned l;
+	register unsigned j, k;
+	register long curpos, newpos;
+
+	l = 0;
+	curpos = fp->offset + (fp->curlsn << FILESHFT);
+	newpos = curpos + len;
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_filerd():  len=%u, curpos=%ld, newpos=%ld, curlen=%ld\n",
+			len, curpos, newpos, fp->curlen);
+#endif
+
+	if (newpos GT fp->curlen) {
+
+		len = fp->curlen - curpos;
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("_filerd():  len adjusted to %u\n", len);
+#endif
+	}
+
+	if (fp->offset) {	/* see if we start in the middle of a sector */
+
+		if ((l = BPSEC - fp->offset) > len)	/* see what we need */
+			l = len;
+
+		if (_getsec(fp, buffer, l))	/* read what we can */
+			return(len);	/* return if ERROR */
+	}
+
+	if (k = (len - l) / BPSEC)		/* see what we still need */
+			if ((j = blkrd(fp, buffer + l, k)) NE 0)
+			return((k - j) * BPSEC + l);	/* return bytes read */
+
+	l += k * BPSEC;			/* adjust l by what we just read */
+
+	if (l < len)	/* see if we still need a partial sector */
+		if (_getsec(fp, buffer + l, len - l))	/* read partial sector */
+			return(l);		/* return if ERROR or EOF */
+
+	return(len);				/* return - got the whole thing */
+}
Index: libcio/readrn.c
===================================================================
--- libcio/readrn.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/readrn.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,84 @@
+/*
+   =============================================================================
+	readrn.c -- read a random sector from a file
+	Version 8 -- 1987-12-15 -- D.N. Lynx Crowe
+
+	int
+	ReadRN(fcp, buf)
+	struct fcb *fcp;
+	char *buf;
+
+		Reads a sector from file 'fcp' into 'buf'.  Seeks as needed.
+		Returns 0 if OK, -1 for errors, 1 for EOF (no data returned).
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "stddefs.h"
+#include "biosdefs.h"
+#include "errno.h"
+#include "errdefs.h"
+#include "fspars.h"
+
+#if	DEBUGIT
+extern	short	fsdebug;
+#endif
+
+#if	TBUFFER
+extern	long	_secrd();
+#endif
+
+extern	long	_berrno;
+extern	int	_seek();
+
+/* 
+
+*/
+
+/*
+   =============================================================================
+	ReadRN(fcp, buf) -- Reads a sector from file 'fcp' into 'buf'.
+	Seeks as needed.  Returns SUCCESS (0) if OK,  FAILURE (-1) for errors.
+   =============================================================================
+*/
+
+int
+ReadRN(fcp, buf)
+struct fcb *fcp;
+char *buf;
+{
+	int	sv;		/* seek return code */
+	long	brc;		/* bios return code */
+
+	if (sv = _seek(fcp))		/* try to find the sector we want */
+		if (sv < 0) {
+
+			errno = EIO;		/* I/O error */
+			return(-1);		/* return:  ERROR */
+
+		} else {
+
+			errno = EINVAL;		/* invalid argument */
+			return(1);		/* return:  EOF */
+		}
+
+#if	DEBUGIT
+	if (fsdebug)
+		printf("ReadRN():  curlsn=%ld, curdsn=%ld, offset=%u\n",
+			fcp->curlsn, fcp->curdsn, fcp->offset);
+#endif
+
+#if	TBUFFER
+	if (brc = _secrd(buf, (short)fcp->curdsn)) {
+#else
+	if (brc = BIOS(B_RDWR, 0, buf, 1, (short)fcp->curdsn, 0)) {
+#endif
+
+		_berrno = brc;			/* log the error */
+		errno = EIO;			/* ... as an I/O error */
+		return(FAILURE);		/* return:  ERROR */
+	}
+
+	return(SUCCESS);		/* return:  SUCCESS */
+}
Index: libcio/rename.c
===================================================================
--- libcio/rename.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/rename.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,14 @@
+/*
+   =============================================================================
+	rename.c -- rename a file
+	Version 2 -- 1987-06-29 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+rename(old, new)
+char *old, *new;
+{
+	char buff[60];
+
+	return(-1);		/* return an error for now */
+}
Index: libcio/scan.c
===================================================================
--- libcio/scan.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/scan.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,399 @@
+/*
+   =============================================================================
+	scan.c -- input scan conversion for the portable C I/O Library
+	Version 3 -- 1989-01-16 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+#include "ctype.h"
+
+static int maxwide;
+static int (*gsub)();
+
+extern char *index();
+
+static char *scnstr;
+static char quit;
+
+/* 
+
+*/
+
+static
+long
+getnum(list, values, base)
+char *list;
+char *values;
+int base;
+{
+	register long val;
+	register char *cp;
+	int c;
+	int sign;
+
+	if (maxwide LE 0)
+		return(0L);
+
+	val = sign = 0;
+
+	if ((c = (*gsub)(0)) EQ '-') {
+
+		sign = 1;
+		--maxwide;
+
+	} else if (c EQ '+')
+		--maxwide;
+	else
+		(*gsub)(1);
+
+	while (maxwide--) {
+
+		if ((cp = index(list, (*gsub)(0))) EQ NULL) {
+
+			(*gsub)(1);
+			break;
+		}
+
+		val *= base;
+		val += values[(long)cp - (long)list];
+	}
+
+	if (sign)
+		val = -val;
+
+	return(val);
+}
+
+/* 
+
+*/
+
+static
+skipblk()
+{
+	while (isspace((*gsub)(0)))
+		;
+
+	if ((*gsub)(1) EQ EOF)
+		return(EOF);
+
+	return(0);
+}
+
+static
+sgetc(what)
+{
+	if (what EQ 0) {
+
+		if (*scnstr)
+			return(*scnstr++ & 0x00FF);
+
+		quit = TRUE;
+
+	} else {
+
+		if (!quit)
+			return(*--scnstr & 0x00FF);
+	}
+
+	return(EOF);
+}
+
+/* 
+
+*/
+
+scanfmt(getsub, fmt, args)
+int (*getsub)();
+register char *fmt;
+int **args;
+{
+
+#ifdef FLOAT
+	double getflt(), d;
+#endif
+
+	long lv;
+	int c, count, dontdo, lflag, base;
+	char *cp;
+	char tlist[130];
+
+	static char list[] = "ABCDEFabcdef9876543210";
+
+	static char vals[] = {
+
+		10,11,12,13,14,15,10,11,12,13,14,15,9,8,7,6,5,4,3,2,1,0
+	};
+
+/* 
+
+*/
+	count = 0;
+	gsub = getsub;
+
+	while (c = *fmt++) {
+
+		if (c EQ '%') {
+
+			lflag = dontdo = FALSE;
+			maxwide = 127;
+
+			if (*fmt EQ '*') {
+				++fmt;
+				dontdo = 1;
+			}
+
+			if (isdigit(*fmt)) {
+
+				maxwide = 0;
+
+				do {
+
+					maxwide = maxwide*10 + *fmt - '0';
+
+				} while (isdigit(*++fmt));
+			}
+
+			if (*fmt EQ 'l') {
+
+				lflag = TRUE;
+				++fmt;
+			}
+	
+/* 
+
+*/
+			switch (*fmt++) {
+
+			case '%':
+				c = '%';
+				goto matchit;
+
+			case 'h':	/* specify short (for compatibility) */
+				lflag = FALSE;
+				goto decimal;
+
+			case 'D':
+				lflag = TRUE;
+
+			case 'd':
+	decimal:
+				c = 12;
+				base = 10;
+				goto getval;
+
+			case 'X':
+				lflag = TRUE;
+
+			case 'x':
+				c = 0;
+				base = 16;
+				goto getval;
+
+			case 'O':
+				lflag = TRUE;
+
+			case 'o':
+				c = 14;
+				base = 8;
+	getval:
+				if (skipblk())
+					goto ateof;
+
+				lv = getnum(&list[c], &vals[c], base);
+
+				if (!dontdo) {
+
+					if (lflag)
+						*(long *)(*args++) = lv;
+					else
+						**args++ = lv;
+					++count;
+				}
+
+				break;
+/* 
+
+*/
+
+#ifdef FLOAT
+			case 'E':
+			case 'F':
+				lflag = TRUE;
+
+			case 'e':
+			case 'f':
+				if (skipblk())
+					goto ateof;
+
+				d = getflt(tlist);
+
+				if (!dontdo) {
+
+					if (lflag)
+						*(double *)(*args++) = d;
+					else
+						*(float *)(*args++) = d;
+					++count;
+				}
+
+				break;
+#endif
+
+/* 
+
+*/
+
+			case '[':
+				lflag = FALSE;
+
+				if (*fmt EQ '^' || *fmt EQ '~') {
+
+					++fmt;
+					lflag = TRUE;
+				}
+
+				for (cp = tlist ; (c = *fmt++) != ']' ; )
+					*cp++ = c;
+
+				*cp = 0;
+				goto string;
+
+			case 's':
+				lflag = TRUE;
+				tlist[0] = ' ';
+				tlist[1] = '\t';
+				tlist[2] = '\n';
+				tlist[3] = 0;
+		string:
+				if (skipblk())
+					goto ateof;
+
+				if (!dontdo)
+					cp = *args++;
+
+				while (maxwide--) {
+
+					if ((c = (*gsub)(0)) EQ EOF)
+						break;
+
+					if (lflag ?
+					     (index(tlist, c) NE 0) :
+					     (index(tlist, c) EQ 0)) {
+
+						(*gsub)(1);	/* unget last character */
+						break;
+					}
+
+					if (!dontdo)
+						*cp++ = c;
+				}
+
+				if (!dontdo) {
+
+					*cp = 0;
+					++count;
+				}
+
+				break;
+/* 
+
+*/
+			case 'c':
+				if ((c = (*gsub)(0)) EQ EOF)
+					goto ateof;
+
+				if (!dontdo) {
+
+					*(char *)(*args++) = c;
+					++count;
+				}
+
+				break;
+			}
+
+		} else if (isspace(c)) {
+
+			if (skipblk()) {
+ateof:
+				if (count EQ 0)
+					return(EOF);
+
+				return(count);
+			}
+
+		} else {
+
+matchit:
+			if (skipblk())
+				goto ateof;
+
+			if ((*gsub)(0) != c)
+				return(count);
+		}
+	}
+
+	return(count);
+}
+
+/* 
+
+*/
+
+#ifdef FLOAT
+
+double
+getflt(buffer)
+char *buffer;
+{
+	register int c;
+	char decpt, sign, exp;
+	register char *cp;
+	double atof();
+
+	cp = buffer;
+	sign = exp = decpt = 0;
+
+	while (maxwide--) {
+
+		c = (*gsub)(0);
+
+		if (!sign AND (c EQ '-' OR c EQ '+'))
+			sign = 1;
+		else if (!decpt AND c EQ '.')
+			decpt = 1;
+		else if (!exp AND (c EQ 'e' OR c EQ 'E')) {
+
+			sign = 0;
+			exp = decpt = 1;
+
+		} else if (!isdigit(c)) {
+
+			(*gsub)(1);
+			break;
+		}
+
+		*cp++ = c;
+	}
+
+	*cp = 0;
+	return(atof(buffer));
+}
+
+#endif
+
+/* 
+
+*/
+
+sscanf(string, fmt, args)
+char *string, *fmt;
+int *args;
+{
+	scnstr = string;
+	quit = FALSE;
+	return(scanfmt(sgetc, fmt, &args));
+}
+
Index: libcio/setbuf.c
===================================================================
--- libcio/setbuf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/setbuf.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,27 @@
+/*
+   ============================================================================
+	setbuf.c -- set a stream buffer
+	Version 1 -- 1987-06-26 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#include "stdio.h"
+
+setbuf(stream, buffer)
+register FILE *stream;
+char *buffer;
+{
+	if (stream->_buff)
+		return;
+
+	if (buffer) {
+
+		stream->_buff = buffer;
+		stream->_buflen = BUFSIZ;
+
+	} else {
+
+		stream->_buff = &stream->_bytbuf;
+		stream->_buflen = 1;
+	}
+}
Index: libcio/ungetc.c
===================================================================
--- libcio/ungetc.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/ungetc.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,22 @@
+/*
+   ============================================================================
+	ungetc.c -- 'unget' a character
+	Version 2 -- 1987-06-26 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#include "stdio.h"
+#include "stddefs.h"
+
+int
+ungetc(c, ptr)
+register int c;
+register FILE *ptr;
+{
+	if ((c EQ EOF) OR (ptr->_bp LE ptr->_buff))
+		return(EOF);
+
+	*--ptr->_bp = c;
+
+	return(c);
+}
Index: libcio/unlink.c
===================================================================
--- libcio/unlink.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/unlink.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,46 @@
+/*
+   =============================================================================
+	unlink.c -- unlink (delete) a file
+	Version 6 -- 1987-11-15 -- D.N. Lynx Crowe
+   =============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "biosdefs.h"
+#include "stddefs.h"
+
+#if	DEBUGIT
+extern	short	fsdebug;
+
+extern	int	waitcr();
+#endif
+
+extern	int	DelFile();
+
+/*
+   =============================================================================
+	unlink(name) -- delete file 'name'.
+   =============================================================================
+*/
+
+int
+unlink(name)
+char *name;
+{
+	struct fcb delfcb;
+
+	if (fcbinit(name, &delfcb))
+		return(FAILURE);
+
+#if	DEBUGIT
+	if (fsdebug) {
+
+		printf("unlink(%s):  deletion FCB created\n", name);
+		SnapFCB(&delfcb);
+		waitcr();
+	}
+#endif
+	return(DelFile(&delfcb));
+}
+
Index: libcio/write.c
===================================================================
--- libcio/write.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/write.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,267 @@
+/*
+   ============================================================================
+	write.c -- write() and friends
+	Version 17 -- 1987-10-27 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "biosdefs.h"
+#include "io.h"
+#include "errno.h"
+#include "stddefs.h"
+
+int	_filewr();
+
+extern	int	_badfd(), _conwr(), blkwr();
+extern	int	ReadRN(), WriteRN();
+extern	int	_newcls(), micons(), _ptcl12();
+
+extern	long	miconl();
+
+extern	char	*memset();
+
+extern	short	_fatmod;
+
+extern	unsigned	_thefat[];
+
+extern	struct	bpb	*_thebpb;
+
+#if DEBUGIT
+extern	short	fsdebug;
+#endif
+
+static	int	(*wr_tab[])() = {	/* write routine dispatch table */
+
+	_badfd,		/* 0 - invalid entry */
+	_filewr,	/* 1 - disk file */
+	_conwr		/* 2 - console device */
+};
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	_putsec(fp, buf, len) -- write 'len' bytes from 'buf' on file 'fp'
+   ============================================================================
+*/
+
+int
+_putsec(fp, buf, len)
+register struct fcb *fp;
+char *buf;
+unsigned len;
+{
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec($%08lX, $%08lx, %d):  initial curlsn=%ld\n",
+			fp, buf, len, fp->curlsn);
+#endif
+
+	if ((errno = ReadRN(fp, Wrkbuf)) EQ 1) {	/* try to read sector */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  ReadRN saw EOF at curlsn=%ld, asects=%ld\n",
+			fp->curlsn, fp->asects);
+#endif
+
+		errno = 0;			/* we're at EOF */
+		memset(Wrkbuf, 0x1A, BPSEC);	/* pad end of sector */
+
+	} else if (errno)
+			return(FAILURE);
+
+	memcpy(Wrkbuf + fp->offset, buf, len);	/* move in the new data */
+
+	if ((errno = WriteRN(fp, Wrkbuf)) NE 0) {	/* write the sector */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  WriteRN() FAILED (%d) - curlsn=%ld\n",
+			errno, fp->curlsn);
+#endif
+
+		return(FAILURE);
+	}
+
+	if ((fp->offset = (fp->offset + len) & (BPSEC - 1)) EQ 0) {
+
+		++fp->curlsn;		/* update file position */
+
+		if (_seek(fp) < 0) {
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  _seek() failed - curlsn=%ld, asects=%ld\n",
+			fp->curlsn, fp->asects);
+#endif
+
+			return(FAILURE);
+		}
+	}
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  final curlsn=%ld, offset=%d, len=%d\n",
+			fp->curlsn, fp->offset, len);
+#endif
+
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	_filewr(fp, buffer, len) -- write 'len' bytes on file 'fp'
+	from 'buffer'.
+   ============================================================================
+*/
+
+int
+_filewr(fp, buffer, len)
+register struct fcb *fp;
+register char *buffer;
+register unsigned len;
+{
+	register unsigned j, k, l;
+	int clustr;
+	register long curpos;
+
+	curpos = fp->offset + (fp->curlsn << FILESHFT);	/* get position */
+
+	if (fp->de.bclust EQ 0) {	/* see if we need to allocate */
+
+#if DEBUGIT
+	if (fsdebug)
+		if (curpos)
+			printf("_filewr():  ERROR - bclust EQ 0 and curpos (%ld) NE 0\n",
+				curpos);
+#endif
+
+		if (0 EQ (clustr = _newcls())) {	/* allocate a cluster */
+
+			errno = EIO;
+			return(len);
+		}
+
+		fp->de.bclust = micons(clustr);		/* update FCB */
+		_ptcl12(_thefat, clustr, 0x0FF8);	/* update FAT */
+		_fatmod = TRUE;
+		fp->curdsn = _cl2lsn(_thebpb, clustr);	/* set curdsn */
+		fp->curcls = clustr;
+		fp->clsec = 0;
+		fp->asects = _thebpb->clsiz;
+#if DEBUGIT
+	if (fsdebug) {
+
+		printf("_filewr():  allocated initial cluster=%d, asects=%ld\n",
+			clustr, fp->asects);
+		SnapFCB(fp);
+	}
+#endif
+	}
+
+	l = 0;			/* zero the length-written counter */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  init pos=%ld, len=%u, curcls=%u, offset=%u\n",
+			curpos, len, fp->curcls, fp->offset);
+#endif
+
+	if (fp->offset) {	/* see if we have a partial sector to fill */
+
+		if ((l = (BPSEC - fp->offset)) > len)
+			l = len;
+
+		if (_putsec(fp, buffer, l))	/* fill up the sector */
+			return(-1);
+	}
+
+	if (k = (len - l) / BPSEC) {	/* write out any full sectors */
+
+		if ((j = blkwr(fp, buffer + l, k)) NE 0) {
+
+			l += (k - j) * BPSEC;	/* update amount written */
+
+			if ((curpos + l) > fp->curlen) 	/* udpate file length */
+				fp->de.flen = miconl(fp->curlen = curpos + l);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  ERROR - curlen=%ld, curlsn=%ld, curdsn=%ld\n",
+			fp->curlen, fp->curlsn, fp->curdsn);
+#endif
+
+			return(l);
+		}
+
+		l += k * BPSEC;		/* update amount written */
+	}
+/* 
+
+*/
+	if (l < len) {			/* write out partial sector at end */
+
+		if (_putsec(fp, buffer + l, len - l)) {
+
+			if ((curpos + l) > fp->curlen)	/* update file length */
+				fp->de.flen = miconl(fp->curlen = curpos + l);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  ERROR - curlen=%ld, curlsn=%ld, curdsn=%ld\n",
+			fp->curlen, fp->curlsn, fp->curdsn);
+#endif
+
+			return(l);
+		}
+	}
+
+	if ((curpos + len) > fp->curlen) 		/* update file length */
+		fp->de.flen = miconl(fp->curlen = curpos + len);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  final curlen=%ld, flen=$%08lX, curlsn=%ld, curdsn=%ld\n",
+			fp->curlen, fp->de.flen, fp->curlsn, fp->curdsn);
+#endif
+
+	return(len);
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	write(fd, buff, len) -- write 'len' bytes from 'buff' on file 'fd'
+   ============================================================================
+*/
+
+int
+write(fd, buff, len)
+int fd;
+char *buff;
+unsigned len;
+{
+	register struct channel *chp;
+
+	if ((fd < 0) OR (fd > MAXCHAN)) {
+
+		errno = EBADF;
+		return(-1);
+	}
+
+	chp = &chantab[fd];
+
+	return((*wr_tab[chp->c_write])(chp->c_arg, buff, len));
+}
Index: libcio/writern.c
===================================================================
--- libcio/writern.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
+++ libcio/writern.c	(revision 109c83b4de0a1be1740921110e1aab18add40866)
@@ -0,0 +1,267 @@
+/*
+   ============================================================================
+	write.c -- write() and friends
+	Version 17 -- 1987-10-27 -- D.N. Lynx Crowe
+   ============================================================================
+*/
+
+#define	DEBUGIT		0
+
+#include "biosdefs.h"
+#include "io.h"
+#include "errno.h"
+#include "stddefs.h"
+
+int	_filewr();
+
+extern	int	_badfd(), _conwr(), blkwr();
+extern	int	ReadRN(), WriteRN();
+extern	int	_newcls(), micons(), _ptcl12();
+
+extern	long	miconl();
+
+extern	char	*memset();
+
+extern	short	_fatmod;
+
+extern	unsigned	_thefat[];
+
+extern	struct	bpb	*_thebpb;
+
+#if DEBUGIT
+extern	short	fsdebug;
+#endif
+
+static	int	(*wr_tab[])() = {	/* write routine dispatch table */
+
+	_badfd,		/* 0 - invalid entry */
+	_filewr,	/* 1 - disk file */
+	_conwr		/* 2 - console device */
+};
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	_putsec(fp, buf, len) -- write 'len' bytes from 'buf' on file 'fp'
+   ============================================================================
+*/
+
+int
+_putsec(fp, buf, len)
+register struct fcb *fp;
+char *buf;
+unsigned len;
+{
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec($%08lX, $%08lx, %d):  initial curlsn=%ld\n",
+			fp, buf, len, fp->curlsn);
+#endif
+
+	if ((errno = ReadRN(fp, Wrkbuf)) EQ 1) {	/* try to read sector */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  ReadRN saw EOF at curlsn=%ld, asects=%ld\n",
+			fp->curlsn, fp->asects);
+#endif
+
+		errno = 0;			/* we're at EOF */
+		memset(Wrkbuf, 0x1A, BPSEC);	/* pad end of sector */
+
+	} else if (errno)
+			return(FAILURE);
+
+	memcpy(Wrkbuf + fp->offset, buf, len);	/* move in the new data */
+
+	if ((errno = WriteRN(fp, Wrkbuf)) NE 0) {	/* write the sector */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  WriteRN() FAILED (%d) - curlsn=%ld\n",
+			errno, fp->curlsn);
+#endif
+
+		return(FAILURE);
+	}
+
+	if ((fp->offset = (fp->offset + len) & (BPSEC - 1)) EQ 0) {
+
+		++fp->curlsn;		/* update file position */
+
+		if (_seek(fp) < 0) {
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  _seek() failed - curlsn=%ld, asects=%ld\n",
+			fp->curlsn, fp->asects);
+#endif
+
+			return(FAILURE);
+		}
+	}
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_putsec():  final curlsn=%ld, offset=%d, len=%d\n",
+			fp->curlsn, fp->offset, len);
+#endif
+
+	return(SUCCESS);
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	_filewr(fp, buffer, len) -- write 'len' bytes on file 'fp'
+	from 'buffer'.
+   ============================================================================
+*/
+
+int
+_filewr(fp, buffer, len)
+register struct fcb *fp;
+register char *buffer;
+register unsigned len;
+{
+	register unsigned j, k, l;
+	int clustr;
+	register long curpos;
+
+	curpos = fp->offset + (fp->curlsn << FILESHFT);	/* get position */
+
+	if (fp->de.bclust EQ 0) {	/* see if we need to allocate */
+
+#if DEBUGIT
+	if (fsdebug)
+		if (curpos)
+			printf("_filewr():  ERROR - bclust EQ 0 and curpos (%ld) NE 0\n",
+				curpos);
+#endif
+
+		if (0 EQ (clustr = _newcls())) {	/* allocate a cluster */
+
+			errno = EIO;
+			return(len);
+		}
+
+		fp->de.bclust = micons(clustr);		/* update FCB */
+		_ptcl12(_thefat, clustr, 0x0FF8);	/* update FAT */
+		_fatmod = TRUE;
+		fp->curdsn = _cl2lsn(_thebpb, clustr);	/* set curdsn */
+		fp->curcls = clustr;
+		fp->clsec = 0;
+		fp->asects = _thebpb->clsiz;
+#if DEBUGIT
+	if (fsdebug) {
+
+		printf("_filewr():  allocated initial cluster=%d, asects=%ld\n",
+			clustr, fp->asects);
+		SnapFCB(fp);
+	}
+#endif
+	}
+
+	l = 0;			/* zero the length-written counter */
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  init pos=%ld, len=%u, curcls=%u, offset=%u\n",
+			curpos, len, fp->curcls, fp->offset);
+#endif
+
+	if (fp->offset) {	/* see if we have a partial sector to fill */
+
+		if ((l = (BPSEC - fp->offset)) > len)
+			l = len;
+
+		if (_putsec(fp, buffer, l))	/* fill up the sector */
+			return(-1);
+	}
+
+	if (k = (len - l) / BPSEC) {	/* write out any full sectors */
+
+		if ((j = blkwr(fp, buffer + l, k)) NE 0) {
+
+			l += (k - j) * BPSEC;	/* update amount written */
+
+			if ((curpos + l) > fp->curlen) 	/* udpate file length */
+				fp->de.flen = miconl(fp->curlen = curpos + l);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  ERROR - curlen=%ld, curlsn=%ld, curdsn=%ld\n",
+			fp->curlen, fp->curlsn, fp->curdsn);
+#endif
+
+			return(l);
+		}
+
+		l += k * BPSEC;		/* update amount written */
+	}
+/* 
+
+*/
+	if (l < len) {			/* write out partial sector at end */
+
+		if (_putsec(fp, buffer + l, len - l)) {
+
+			if ((curpos + l) > fp->curlen)	/* update file length */
+				fp->de.flen = miconl(fp->curlen = curpos + l);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  ERROR - curlen=%ld, curlsn=%ld, curdsn=%ld\n",
+			fp->curlen, fp->curlsn, fp->curdsn);
+#endif
+
+			return(l);
+		}
+	}
+
+	if ((curpos + len) > fp->curlen) 		/* update file length */
+		fp->de.flen = miconl(fp->curlen = curpos + len);
+
+#if DEBUGIT
+	if (fsdebug)
+		printf("_filewr():  final curlen=%ld, flen=$%08lX, curlsn=%ld, curdsn=%ld\n",
+			fp->curlen, fp->de.flen, fp->curlsn, fp->curdsn);
+#endif
+
+	return(len);
+}
+
+/* 
+
+*/
+
+/*
+   ============================================================================
+	write(fd, buff, len) -- write 'len' bytes from 'buff' on file 'fd'
+   ============================================================================
+*/
+
+int
+write(fd, buff, len)
+int fd;
+char *buff;
+unsigned len;
+{
+	register struct channel *chp;
+
+	if ((fd < 0) OR (fd > MAXCHAN)) {
+
+		errno = EBADF;
+		return(-1);
+	}
+
+	chp = &chantab[fd];
+
+	return((*wr_tab[chp->c_write])(chp->c_arg, buff, len));
+}
