/*
 * lib.h
 *
 * Copyright 2002, Minoru Murashima. All rights reserved.
 * Distributed under the terms of the BSD License.
 *
 * lib.c、lib.S用ヘッダーファイル
 */


#ifndef lib_h
#define lib_h


#include"types.h"
#include"segment.h"


#ifndef ASM_FILE


#define ROUNDUP(a,b) (((uint)(a)+(b)-1)/(b)*(b))
#define ROUNDDOWN(a,b) ((uint)(a)/(b)*(b))
#define ROUNDUP_DIV(a,b) (((uint)(a)+(b)-1)/(b))


extern int (*write_tty)(const char*,size_t);
extern void printk(const char*,...);
extern void idle();
extern int read_tr();
extern long long rdtsc();
extern void micro_timer(uint);
extern void mili_timer(uint);
extern char *strcpy(char*,const char*);
extern int strcmp(const char*,const char*);
extern size_t strlen(const char*);
extern int atoi(const char*);
extern void *memcpy(void*,const void*, size_t);
extern void *memset(void*,int,size_t);
extern void *memcpy_to_user(void *,const void*,size_t);
extern void *memcpy_from_user(void *,const void*,size_t);


extern inline void cli()
{
	asm volatile("cli");
}

extern inline void sti()
{
	asm volatile("sti");
}

extern inline void outb(int port,uchar value)
{
	asm volatile(
		"outb	%%dx"
		::"d"(port),"a"(value)
	);
}

extern inline uchar inb(int port)
{
	uchar rest;


	asm volatile(
		"inb	%%dx"
		:"=a"(rest):"d"(port)
	);

	return rest;
}

extern inline void outw(int port,ushort value)
{
	asm volatile(
		"outw	%%dx"
		::"d"(port),"a"(value)
	);
}

extern inline ushort inw(int port)
{
	ushort rest;


	asm volatile(
		"inw	%%dx"
		:"=a"(rest):"d"(port)
	);

	return rest;
}

extern inline void outdw(int port,uint value)
{
	asm volatile(
		"outl	%%dx"
		::"d"(port),"a"(value)
	);
}

extern inline uint indw(int port)
{
	uint rest;


	asm volatile(
		"inl	%%dx"
		:"=a"(rest):"d"(port)
	);

	return rest;
}

extern inline char *strcpy(char *s1,const char *s2)
{
	char *p=s1;


	while((*p++=*s2++)!='\0');

	return s1;
}

extern inline char *strncpy(char *s1,const char *s2,size_t n)
{
	while(--n>=0)s1[n]=s2[n];

	return s1;
}


extern inline size_t strlen(const char *s)
{
	const char *p=s;


	while(*p++!='\0');

	return (size_t)(p-s-1);
}

extern inline int strcmp(const char *s1,const char *s2)
{
	while(*s1==*s2++)
		if(*s1++=='\0')return 0;

	if(*s1>*--s2)return 1;
	return -1;
}


#endif


#endif
