/* vim: set filetype=c:
 *
 * conio.h86  -  Console I/O for target system
 *
 * Copyright (C) 2003-2007 Gero Kuhlmann   <gero@gkminix.han.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: conio.h86,v 1.10 2007/01/06 18:30:54 gkminix Exp $
 */


#ifndef I386_CONIO_H86
#define I386_CONIO_H86



/*
 **************************************************************************
 *
 * This file can not be included into assembler source
 */
#ifndef _ASSEMBLY_

#include <common.h86>
#include <i386/stdarg.h86>



/*
 **************************************************************************
 *
 * Print a character onto the console
 */
__nb_inline__ char charout(char c)
{
  __u8 d0;

  __asm__ __volatile__(
	"call prnchr"
	: "=&a" (d0)
	: "0" ((__u8)c));
  return(c);
}



/*
 **************************************************************************
 *
 * Print a CR/LF onto the console
 */
__nb_inline__ void crlfout(void)
{
  __u16 d0;

  __asm__ __volatile__(
	"call prcrlf"
	: "=&a" (d0)
	: /* no input */);
}



/*
 **************************************************************************
 *
 * Print a zero-terminated string onto the console
 */
__nb_inline__ void strout(char *str)
{
  __u16 d0, d1;

  __asm__ __volatile__(
	"call prnstr"
	: "=&S" (d0), "=&a" (d1)
	: "0" ((__u16)((int)str)));
}

#define puts(s)		strout(s); crlfout()



/*
 **************************************************************************
 *
 * Print a number onto the console
 */
__nb_inline__ void numout(unsigned long n, unsigned short base)
{
  __u16 d0;
  __u32 d1;

  __asm__ __volatile__(
	"call prnnum"
	: "=&d" (d0), "=&a" (d1)
	: "0" ((__u16)base), "1" ((__u32)n));
}



/*
 **************************************************************************
 *
 * Convert a number into a string suitable for printing
 *
 * This routine returns a pointer into a static memory block, and should
 * only be used inside the target runtime library.
 */
__nb_inline__ char *__numcvt(unsigned long n, unsigned short base)
{
  __u16 d0;
  __u32 d1;
  __u16 ret;

  __asm__ __volatile__(
	"call cvtnum"
	: "=&d" (d0), "=&a" (d1), "=&S" (ret)
	: "0" ((__u16)base), "1" ((__u32)n)
	: "memory");
  return((char *)((unsigned int)ret));
}



/*
 **************************************************************************
 *
 * ANSI output support routines
 */
extern void ansiinit(void);
extern void ansiout(char ch);
extern void ansigetpos(short *x, short *y);
extern void ansisetpos(short x, short y);



/*
 **************************************************************************
 *
 * Pointer to an alternate output routine
 */
extern void (* altout)(char);



/*
 **************************************************************************
 *
 * Special printf() routine for the bootrom
 */
extern size_t bprintf(const char *fmt, ...);



/*
 **************************************************************************
 *
 * External console-I/O output routines
 */
extern char cputc(char ch);
extern size_t cputs(char *s);
extern size_t cwrite(char *buf, size_t len);
extern size_t cprintf(const char *fmt, ...)
				__attribute__((format (printf, 1, 2)));

#ifdef _BOOTROM_
# define printf	bprintf
#else
# define printf	cprintf
#endif
#define putchar	cputc



/*
 **************************************************************************
 *
 * Wait for the user pressing a key until timeout or forever, if
 * timeout is 0. Return -1 if timeout reached.
 */
__nb_inline__ short getkey(unsigned short timeout)
{
  __u16 ret;

  __asm__ __volatile__(
	"call keywait"
	: "=&a" (ret)
	: "0" ((__u16)timeout));
  return(ret == 0xFFFF ? -1 : (short)(ret & 0x00FF));
}



/*
 **************************************************************************
 *
 * Check if a key has been pressed, return -1 if no key pressed
 */
__nb_inline__ short chkkey(void)
{
  __u16 ret;

  __asm__ __volatile__(
	"call keycheck"
	: "=&a" (ret)
	: /* no input */ );
  return(ret == 0xFFFF ? -1 : (short)(ret & 0x00FF));
}



/*
 **************************************************************************
 *
 * External console-I/O input routines
 */
extern void cflush(void);
extern char cgetc(void);
extern char cungetc(char ch);
extern char *cgets(char *s, size_t count);
extern size_t cread(char *buf, size_t len);
extern size_t cscanf(const char *fmt, ...)
				__attribute__((format (scanf, 1, 2)));

#define scanf	cscanf
#define EOF	((size_t)(-1))


#endif /* _ASSEMBLY_ */

#endif

