/*-
 * Copyright (c) 2006 Robert N. M. Watson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include "borland.h"
#include "cons.h"
#include "emul.h"

#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *
itoa(int value, char *buffer, int radix)
{

	if (radix == 10)
		sprintf(buffer, "%d", value);
	else
		sprintf(buffer, "???");
	return (buffer);
}

char *
ltoa(long value, char *buffer, int radix)
{

	if (radix == 10)
		sprintf(buffer, "%ld", value);
	else
		sprintf(buffer, "???");
	return (buffer);
}

char *
ultoa(unsigned long value, char *buffer, int radix)
{

	if (radix == 10)
		sprintf(buffer, "%ld", value);
	else
		sprintf(buffer, "???");
	return (buffer);
}

char *
gcvt(double value, int num, char *buffer)
{

	snprintf(buffer, num - 1, "%f", value);
	return (buffer);
}

char *
strupr(char *string)
{
	char *c;

	for (c = string; c != NULL; c++)
		*c = toupper(*c);
	return (string);
}

int
getch(void)
{

	errno = ENOSYS;
	err(-1, "getch");
}

int
getche(void)
{

	errno = ENOSYS;
	err(-1, "getche");
}

int
peek(unsigned int segment, unsigned int offset)
{

	panic("peek(0x%04x, 0x%04x): %s", strerror(ENOSYS), segment, offset);
}

char
peekb(unsigned int segment, unsigned int offset)
{
	char ch;

	if (segment == 0x0040 && offset == 0x0049) {
		/*
		 * Per http://heim.ifi.uio.no/~stanisls/helppc/int_10-0.html
		 * use 80x25 in color.
		 */
		return (3);
	} else if (segment == 0x0000 && offset == 0x0484) {
		/*
		 * Appears to be a request for the bottom end of the screen.
		 */
		return (24);
	} else if (segment == 0x0000 && offset == 0x0417) {
		/*
		 * Keyboard status byte, sort of a bit emulated.
		 */
		if (cons_getnumlock())
			ch = 0x10;
		else
			ch = 0;
		return (0);
	}

	panic("peekb(0x%04x, 0x%04x): %s", strerror(ENOSYS), segment, offset);
}

void
farfree(void *ptr)
{

	free(ptr);
}

void *
farmalloc(unsigned long size)
{

	return (malloc(size));
}

int
stricmp(const char *s1, const char *s2)
{

	return (strcasecmp(s1, s2));
}
