blob: 0be77b39328afc957c8aa70b64bbe0641f477a7c [file] [log] [blame]
H. Peter Anvin15436102007-07-11 12:18:45 -07001/* -*- 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/*
H. Peter Anvin15436102007-07-11 12:18:45 -070012 * 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
23void __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... */
H. Peter Anvin8c027ae2007-07-16 11:58:24 -070032 asm volatile("pushal; pushw %%ds; int $0x10; popw %%ds; popal"
H. Peter Anvin15436102007-07-11 12:18:45 -070033 : : "b" (0x0007), "c" (0x0001), "a" (0x0e00|ch));
34}
35
36void __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
50static u8 gettime(void)
51{
52 u16 ax = 0x0200;
53 u16 cx, dx;
54
H. Peter Anvinb0151242007-08-22 16:28:01 -070055 asm volatile("int $0x1a"
56 : "+a" (ax), "=c" (cx), "=d" (dx)
57 : : "ebx", "esi", "edi");
H. Peter Anvin15436102007-07-11 12:18:45 -070058
59 return dx >> 8;
60}
61
62/*
63 * Read from the keyboard
64 */
65int getchar(void)
66{
67 u16 ax = 0;
H. Peter Anvinb0151242007-08-22 16:28:01 -070068 asm volatile("int $0x16" : "+a" (ax));
H. Peter Anvin15436102007-07-11 12:18:45 -070069
70 return ax & 0xff;
71}
72
73static int kbd_pending(void)
74{
75 u8 pending;
H. Peter Anvinb0151242007-08-22 16:28:01 -070076 asm volatile("int $0x16; setnz %0"
77 : "=rm" (pending)
78 : "a" (0x0100));
H. Peter Anvin15436102007-07-11 12:18:45 -070079 return pending;
80}
81
82void kbd_flush(void)
83{
84 for (;;) {
85 if (!kbd_pending())
86 break;
87 getchar();
88 }
89}
90
91int 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}