#include <sys/times.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <stdlib.h>

char readchar(void)
{
	volatile char *pUART_stat = (char*)0x80000008;
	volatile char *pUART_data = (char*)0x80000004;

	while(!(0x10 & *pUART_stat));

	return *pUART_data;
}

void writechar(char c)
{
	volatile char *pUART_stat = (char*)0x80000008;
	volatile char *pUART_data = (char*)0x80000004;

	while((0x02 & *pUART_stat) != 0);

	*pUART_data = c;
}

clock_t times(struct tms *buffer)
{
	volatile long *pReg_usec = (long*)0x80000010;
	volatile long *pReg_sec = (long*)0x80000014;
	long sec;

	sec = *pReg_sec;

	if (buffer)
	{
		buffer->tms_utime = sec;
		buffer->tms_stime = 0;
		buffer->tms_cutime = 0;
		buffer->tms_cstime = 0;
	}

	return (clock_t)sec;
}

int gettimeofday(struct timeval *tp, void *tzp)
{
	volatile long *pReg_usec = (long*)0x80000010;
	volatile long *pReg_sec = (long*)0x80000014;

	if (tp)
	{
		tp->tv_sec = *pReg_sec;
		tp->tv_usec = *pReg_usec;
	}

	return 0;
}

int settimeofday(const struct timeval *tp, const struct timezone *tzp)
{
	volatile long *pReg_usec = (long*)0x80000010;
	volatile long *pReg_sec = (long*)0x80000014;
	div_t res;

	res = div(tp->tv_usec, 1E6);

	if (tp)
	{
		*pReg_usec = res.rem;
		*pReg_sec  = tp->tv_sec + res.quot;
	}

	return 0;
}

caddr_t sbrk(int incr)
{
	extern char end;
	static char *heap_end;
	char *prev_heap_end;

	if (heap_end == 0)
		heap_end = &end;

	prev_heap_end = heap_end;
//	if (heap_end + incr > stack_ptr)
//	{
//		_write(1, "Heap and stack collision\n", 25);
//		abort();
//	}

	heap_end += incr;
	return (caddr_t) prev_heap_end;
}

int fstat(int file, struct stat *st)
{
	st->st_mode = S_IFCHR;
	return 0;
}

int lseek(int file, int ptr, int dir)
{
	return 0;
}

int open(const char *name, int flags, int mode)
{
	return -1;
}

int close(int file)
{
	return -1;
}

int read(int file, char *ptr, int len)
{
	return 0;
}

int write(int file, char *ptr, int len)
{
	int i;

	for (i=0; i < len; i++)
		writechar(*ptr++);

	return i;
}

int isatty(int file)
{
	return 1;
}

int sputs(char *pStr)
{
	char *start;
	start = pStr;

	while(*pStr)
		writechar(*(pStr++));

	return pStr - start;
}

void print_byte(char byte)
{
	int i;
	unsigned char c, nibble;

	for (i=0; i < 2; i++)
	{
		nibble = (char)((byte >> 4) & 0xF);
		byte <<= 4;

		if (nibble < 10)
			c = nibble + '0';
		else
			c = nibble + 'A' - 10;

		writechar(c);
	}
}

void print_word(int word)
{
	int i;
	unsigned char c, nibble;

	for (i=0; i < 4; i++)
	{
		c = (char) (word >> 24);
		print_byte(c);
		word <<= 8;
	}
}

