#include <time.h>
#include <stdio.h>
#include <libp.h>
#include <dpmi.h>
#include <llp.h>

extern int maxfiles;

unsigned char inbuf[512];

FILE output_file = { 0, _F_WRIT | _F_LBUF | _F_TERM,1,0,0,0,0,0,FILTOK };
FILE input_file = { 0, _F_READ | _F_LBUF | _F_TERM,0,0,512,inbuf,inbuf,0,FILTOK };
FILE error_file = { 0, _F_WRIT | _F_LBUF | _F_TERM,1,0,0,0,0,0,FILTOK };

#undef stdin
#undef stdout
#undef stderr

FILE *stdin = &input_file;
FILE *stdout = &output_file;
FILE *stderr = &error_file;

extern int maxfiles;

void _ll_init(void)
{
	_pstreams[0] = &input_file;
	_pstreams[1] = &output_file;
	_pstreams[2] = &error_file;
	maxfiles = 3;
}
int _ll_open(char *name, int flags)
{
	DPMI_REGS regs;
	regs.d.eax = flags;
	regs.h.dx = __nametodta(name,0);
	return __doscall(0x3d,&regs);
}
int _ll_creat(char *name, int flags)
{
	DPMI_REGS regs;
	regs.d.ecx = 0;
	regs.h.dx = __nametodta(name,0);
	return __doscall(0x3c,&regs);
}
int _ll_close(int fd)
{
	DPMI_REGS regs;
	if (fd < 5)
		return 0;
	regs.h.bx = fd;
	__doscall(0x3e,&regs);
	return 0;
}
size_t _ll_getpos(int fd)
{
	DPMI_REGS regs;
	regs.h.bx = fd;
	regs.h.dx =0;
	regs.h.cx = 0;
	regs.b.al=1;
	__doscall(0x42,&regs);
	if (regs.h.flags & 1)
		return -1;
	return ((regs.h.dx << 16) + regs.h.ax);
}
int _ll_flags(int flags)
{
	if (flags & _F_WRIT)
		if (flags & _F_READ)
			return 2;
		else
			return 1;
	else
		return 0;
} 

int _ll_seek(int fd, size_t pos, int origin)
{
	DPMI_REGS regs;
	regs.h.bx = fd;
	regs.h.cx = pos >> 16;
	regs.h.dx = pos & 65535;
	regs.b.al = origin;
	__doscall(0x42,&regs);
	if (regs.h.flags & 1)
		return -1;
	
	return 0;
}
int _ll_rename(char *old , char *new)
{
	DPMI_REGS regs;
	regs.h.dx = __nametodta(old,0);
	regs.h.di = __nametodta(new,256);
	__doscall(0x56,&regs);
	if (regs.h.flags & 1)
		return -1;
	
	return 0;
}
int _ll_remove(char *name)
{
	DPMI_REGS regs;
	regs.h.dx = __nametodta(name,0);
	__doscall(0x41,&regs);
	if (regs.h.flags & 1)
		return -1;
	
	return 0;
}
int _ll_write(int fd, void *buf, size_t size)
{
	DPMI_REGS regs;
	int mod = size%2048,i,tsize = 0;
	for (i=0; i < (size&-2048); i +=2048) {
		regs.h.dx = __buftodta((char *)buf+i,2048);
		regs.h.bx = fd;
		regs.h.cx = 2048;
		__doscall(0x40,&regs);
		if (regs.h.flags & 1)
			return -1;
		tsize += regs.h.ax;
	}
	regs.h.dx = __buftodta((char *)buf+i,mod);
	regs.h.bx = fd;
	regs.h.cx = mod;
	__doscall(0x40,&regs);
	if (regs.h.flags & 1)
		return -1;
	tsize += regs.h.ax;
	return tsize;
}
int _ll_read(int fd, void *buf, size_t size)
{
	DPMI_REGS regs;
	int mod = size %2048,i, tsize = 0;
	for (i=0; i < (size & -2048); i += 2048) {
		regs.h.dx = 0;
		regs.h.bx = fd;
		regs.h.cx = 2048;
		__doscall(0x3f,&regs);
		if (regs.h.flags & 1)
			return -1;
		__dtatobuf((char *)buf+i,2048);
		tsize += regs.h.ax;
		if (regs.h.ax < 2048)
			return tsize;
	}
	regs.h.dx = 0;
	regs.h.bx = fd;
	regs.h.cx = mod;
	__doscall(0x3f,&regs);
	tsize += regs.h.ax;
	if (regs.h.flags & 1)
		return -1;
	__dtatobuf((char *)buf+i,mod);
	return tsize;
}