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
putchar(int ch)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
puts(const char * str)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
gettime(void)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 */
getchar(void)65 int getchar(void)
66 {
67 u16 ax = 0;
68 asm volatile("int $0x16" : "+a" (ax));
69
70 return ax & 0xff;
71 }
72
kbd_pending(void)73 static int kbd_pending(void)
74 {
75 u8 pending;
76 asm volatile("int $0x16; setnz %0"
77 : "=qm" (pending)
78 : "a" (0x0100));
79 return pending;
80 }
81
kbd_flush(void)82 void kbd_flush(void)
83 {
84 for (;;) {
85 if (!kbd_pending())
86 break;
87 getchar();
88 }
89 }
90
getchar_timeout(void)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