1 /* -*- linux-c -*- ------------------------------------------------------- * 2 * 3 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright 2007 rPath, Inc. - All Rights Reserved 5 * 6 * This file is part of the Linux kernel, and is made available under 7 * the terms of the GNU General Public License version 2. 8 * 9 * ----------------------------------------------------------------------- */ 10 11 /* 12 * arch/i386/boot/tty.c 13 * 14 * Very simple screen I/O 15 * XXX: Probably should add very simple serial I/O? 16 */ 17 18 #include "boot.h" 19 20 /* 21 * These functions are in .inittext so they can be used to signal 22 * error during initialization. 23 */ 24 25 void __attribute__((section(".inittext"))) putchar(int ch) 26 { 27 unsigned char c = ch; 28 29 if (c == '\n') 30 putchar('\r'); /* \n -> \r\n */ 31 32 /* int $0x10 is known to have bugs involving touching registers 33 it shouldn't. Be extra conservative... */ 34 asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal" 35 : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch)); 36 } 37 38 void __attribute__((section(".inittext"))) puts(const char *str) 39 { 40 int n = 0; 41 while (*str) { 42 putchar(*str++); 43 n++; 44 } 45 } 46 47 /* 48 * Read the CMOS clock through the BIOS, and return the 49 * seconds in BCD. 50 */ 51 52 static u8 gettime(void) 53 { 54 u16 ax = 0x0200; 55 u16 cx, dx; 56 57 asm volatile("int $0x1a" 58 : "+a" (ax), "=c" (cx), "=d" (dx) 59 : : "ebx", "esi", "edi"); 60 61 return dx >> 8; 62 } 63 64 /* 65 * Read from the keyboard 66 */ 67 int getchar(void) 68 { 69 u16 ax = 0; 70 asm volatile("int $0x16" : "+a" (ax)); 71 72 return ax & 0xff; 73 } 74 75 static int kbd_pending(void) 76 { 77 u8 pending; 78 asm volatile("int $0x16; setnz %0" 79 : "=rm" (pending) 80 : "a" (0x0100)); 81 return pending; 82 } 83 84 void kbd_flush(void) 85 { 86 for (;;) { 87 if (!kbd_pending()) 88 break; 89 getchar(); 90 } 91 } 92 93 int getchar_timeout(void) 94 { 95 int cnt = 30; 96 int t0, t1; 97 98 t0 = gettime(); 99 100 while (cnt) { 101 if (kbd_pending()) 102 return getchar(); 103 104 t1 = gettime(); 105 if (t0 != t1) { 106 cnt--; 107 t0 = t1; 108 } 109 } 110 111 return 0; /* Timeout! */ 112 } 113