2007-07-11 12:18:45 -07:00
/* -*- linux-c -*- ------------------------------------------------------- *
*
* Copyright ( C ) 1991 , 1992 Linus Torvalds
* Copyright 2007 rPath , Inc . - All Rights Reserved
*
* This file is part of the Linux kernel , and is made available under
* the terms of the GNU General Public License version 2.
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
* Very simple screen I / O
* XXX : Probably should add very simple serial I / O ?
*/
# include "boot.h"
/*
* These functions are in . inittext so they can be used to signal
* error during initialization .
*/
void __attribute__ ( ( section ( " .inittext " ) ) ) putchar ( int ch )
{
unsigned char c = ch ;
if ( c = = ' \n ' )
putchar ( ' \r ' ) ; /* \n -> \r\n */
/* int $0x10 is known to have bugs involving touching registers
it shouldn ' t . Be extra conservative . . . */
2007-07-16 11:58:24 -07:00
asm volatile ( " pushal; pushw %%ds; int $0x10; popw %%ds; popal "
2007-07-11 12:18:45 -07:00
: : " b " ( 0x0007 ) , " c " ( 0x0001 ) , " a " ( 0x0e00 | ch ) ) ;
}
void __attribute__ ( ( section ( " .inittext " ) ) ) puts ( const char * str )
{
int n = 0 ;
while ( * str ) {
putchar ( * str + + ) ;
n + + ;
}
}
/*
* Read the CMOS clock through the BIOS , and return the
* seconds in BCD .
*/
static u8 gettime ( void )
{
u16 ax = 0x0200 ;
u16 cx , dx ;
2007-08-22 16:28:01 -07:00
asm volatile ( " int $0x1a "
: " +a " ( ax ) , " =c " ( cx ) , " =d " ( dx )
: : " ebx " , " esi " , " edi " ) ;
2007-07-11 12:18:45 -07:00
return dx > > 8 ;
}
/*
* Read from the keyboard
*/
int getchar ( void )
{
u16 ax = 0 ;
2007-08-22 16:28:01 -07:00
asm volatile ( " int $0x16 " : " +a " ( ax ) ) ;
2007-07-11 12:18:45 -07:00
return ax & 0xff ;
}
static int kbd_pending ( void )
{
u8 pending ;
2007-08-22 16:28:01 -07:00
asm volatile ( " int $0x16; setnz %0 "
: " =rm " ( pending )
: " a " ( 0x0100 ) ) ;
2007-07-11 12:18:45 -07:00
return pending ;
}
void kbd_flush ( void )
{
for ( ; ; ) {
if ( ! kbd_pending ( ) )
break ;
getchar ( ) ;
}
}
int getchar_timeout ( void )
{
int cnt = 30 ;
int t0 , t1 ;
t0 = gettime ( ) ;
while ( cnt ) {
if ( kbd_pending ( ) )
return getchar ( ) ;
t1 = gettime ( ) ;
if ( t0 ! = t1 ) {
cnt - - ;
t0 = t1 ;
}
}
return 0 ; /* Timeout! */
}