#include <sys/times.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include "libsys_boot.h"

// ---------------------------------------------------------------------------------
// MIPS specific
UINT32 CP0_SR_read(void)
{
	UINT32 result;

	__asm
	(
		"mfc0   %[val], $12\n"
		: [val] "=r" (result)
	);

	return result;
}

void CP0_SR_write(UINT32 val)
{
	__asm
	(
		"mtc0   %[val], $12\n"
		: /* no output */
		: [val] "r" (val)
	);
}

UINT32 CP0_CR_read(void)
{
	UINT32 result;

	__asm
	(
		"mfc0   %[val], $13\n"
		: [val] "=r" (result)
	);

	return result;
}

void CP0_CR_write(UINT32 val)
{
	__asm
	(
		"mtc0   %[val], $13\n"
		:
		: [val] "r" (val)
	);
}

UINT32 CP0_PRID_read(void)
{
	UINT32 result;

	__asm
	(
		"mfc0   %[val], $15\n"
		: [val] "=r" (result)
	);

	return result;
}

// ---------------------------------------------------------------------------------
char readchar(void)
{
	volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
	volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;

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

	return (char)*pUART_data;
}

void writechar(char c)
{
	volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
	volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;

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

	*pUART_data = (UINT32)c;
}

void _putchar(char c)
{
	if (c == 0x0A)
	{
		writechar(0x0D);
	}
	writechar(c);
}

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

	while(*pStr)
		_putchar(*(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;

		_putchar(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;
	}
}

