/* Copyright (C) 1981,1982 by Manx Software Systems */
#include "libc.h"
#define MAXFILE	6	/* maximum number of files open at one time */

struct fcb {
	char f_driv;
	char f_name[8];
	char f_type[3];
	char f_ext;
	char f_resv[2];
	char f_rc;
	char f_sydx[16];
	char f_cr;
	unsigned f_record; char f_overfl;
};

#define	OPNFIL	15
#define CLSFIL	16
#define DELFIL	19
#define MAKFIL	22
#define SETDMA	26
#define READ	33
#define WRITE	34
#define FILSIZ	35

#define E_NOFILE	-1
#define E_BADNAM	-2
#define E_BADREQ	-3
#define E_NOFCB		-4

int errno;
struct _sctparm sctparm = {
	128,0x7f,7,0x1a
} ;

static struct fcbtab {
	struct fcb fcb;
	char mode;
} fcbtab[MAXFILE];

open(name,type)
char *name;
{
	register int i;
	register struct fcbtab *fp;

	for ( fp = fcbtab ; fp < fcbtab+MAXFILE ; ++fp )
		if ( fp->mode == 0 )
			goto havefcb;
	errno = E_NOFCB;
	return -1;

havefcb:
	if ( fcbinit(name,&fp->fcb) ) {
		errno = E_BADNAM;
		return -1;
	}
	switch ( type ) {
	case 0:
	case 2:
		if ( CPM(OPNFIL,&fp->fcb) == 0xff ) {
			errno = E_NOFILE;
			return -1;
		}
		break;
	case 1:
		CPM(DELFIL,&fp->fcb);
		if ( CPM(MAKFIL,&fp->fcb) == 0xff ) {
			errno = E_NOFILE;
			return -1;
		}
		break;
	default:
		errno = E_BADREQ;
		return -1;
	}
	fp->mode = type + 1;
	fp->fcb.f_record = fp->fcb.f_overfl = 0;
	return fp-fcbtab;
}

close(fd)
{
	register struct fcbtab *fp;

	fp = &fcbtab[fd];
	if ( fp->mode > 1 )
		CPM(CLSFIL,&fp->fcb);
	fp->mode = 0;
	return 0;
}

read(fd,buffer,len)
char *buffer; unsigned len;
{
	register struct fcbtab *fp;
	register unsigned used;

	fp = &fcbtab[fd];
	for ( used = 0 ; used < len ; used += 128 ) {
		CPM(SETDMA,buffer+used);
		if ( (errno = CPM(READ,&fp->fcb)) != 0 )
			break;
		++fp->fcb.f_record;
	}
	return used;
}

write(fd,buffer,len)
char *buffer; unsigned len;
{
	register struct fcbtab *fp;
	register unsigned used;

	fp = &fcbtab[fd];
	for ( used = 0 ; used < len ; used += 128 ) {
		CPM(SETDMA,buffer+used);
		if ( (errno = CPM(WRITE,&fp->fcb)) != 0 )
			break;
		++fp->fcb.f_record;
	}
	return used;
}

posit(fd,sector)
{
	register struct fcbtab *fp;

	fp = &fcbtab[fd];
	fp->fcb.f_record = sector;
	fp->fcb.f_overfl = 0;
	return 0;
}

fsize(fd)
{
	register struct fcbtab *fp;

	fp = &fcbtab[fd];
	CPM(FILSIZ,&fp->fcb);
	return fp->fcb.f_record;
}

struct fcb *
fcbaddr(fd)
{
	return &(fcbtab[fd].fcb);
}

unlink(name)
char *name;
{
	struct fcb delfcb;

	fcbinit(name,&delfcb);
	CPM(DELFIL,&delfcb);
}

getchar()
{
	register int c;

	if ((c = CPM(1,0)) == '\r' ) {
		CPM(2,'\n');
		c = '\n';
	} else if ( c == 0x04 )
		c = -1;
	return c;
}

putchar(c)
int c;
{
	if ( c == '\n' )
		CPM(2,'\r');
	CPM(2,c);
	return c;
}
