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