Commit | Line | Data |
---|---|---|
1543610a PA |
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 | /* | |
1543610a PA |
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... */ | |
8c027ae2 | 32 | asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal" |
1543610a PA |
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 | ||
b015124e PA |
55 | asm volatile("int $0x1a" |
56 | : "+a" (ax), "=c" (cx), "=d" (dx) | |
57 | : : "ebx", "esi", "edi"); | |
1543610a PA |
58 | |
59 | return dx >> 8; | |
60 | } | |
61 | ||
62 | /* | |
63 | * Read from the keyboard | |
64 | */ | |
65 | int getchar(void) | |
66 | { | |
67 | u16 ax = 0; | |
b015124e | 68 | asm volatile("int $0x16" : "+a" (ax)); |
1543610a PA |
69 | |
70 | return ax & 0xff; | |
71 | } | |
72 | ||
73 | static int kbd_pending(void) | |
74 | { | |
75 | u8 pending; | |
b015124e | 76 | asm volatile("int $0x16; setnz %0" |
5cf02b7b | 77 | : "=qm" (pending) |
b015124e | 78 | : "a" (0x0100)); |
1543610a PA |
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 | } |