0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "boot.h"
0015
0016 int early_serial_base;
0017
0018 #define XMTRDY 0x20
0019
0020 #define TXR 0
0021 #define LSR 5
0022
0023
0024
0025
0026
0027
0028 static void __section(".inittext") serial_putchar(int ch)
0029 {
0030 unsigned timeout = 0xffff;
0031
0032 while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
0033 cpu_relax();
0034
0035 outb(ch, early_serial_base + TXR);
0036 }
0037
0038 static void __section(".inittext") bios_putchar(int ch)
0039 {
0040 struct biosregs ireg;
0041
0042 initregs(&ireg);
0043 ireg.bx = 0x0007;
0044 ireg.cx = 0x0001;
0045 ireg.ah = 0x0e;
0046 ireg.al = ch;
0047 intcall(0x10, &ireg, NULL);
0048 }
0049
0050 void __section(".inittext") putchar(int ch)
0051 {
0052 if (ch == '\n')
0053 putchar('\r');
0054
0055 bios_putchar(ch);
0056
0057 if (early_serial_base != 0)
0058 serial_putchar(ch);
0059 }
0060
0061 void __section(".inittext") puts(const char *str)
0062 {
0063 while (*str)
0064 putchar(*str++);
0065 }
0066
0067
0068
0069
0070
0071
0072 static u8 gettime(void)
0073 {
0074 struct biosregs ireg, oreg;
0075
0076 initregs(&ireg);
0077 ireg.ah = 0x02;
0078 intcall(0x1a, &ireg, &oreg);
0079
0080 return oreg.dh;
0081 }
0082
0083
0084
0085
0086 int getchar(void)
0087 {
0088 struct biosregs ireg, oreg;
0089
0090 initregs(&ireg);
0091
0092 intcall(0x16, &ireg, &oreg);
0093
0094 return oreg.al;
0095 }
0096
0097 static int kbd_pending(void)
0098 {
0099 struct biosregs ireg, oreg;
0100
0101 initregs(&ireg);
0102 ireg.ah = 0x01;
0103 intcall(0x16, &ireg, &oreg);
0104
0105 return !(oreg.eflags & X86_EFLAGS_ZF);
0106 }
0107
0108 void kbd_flush(void)
0109 {
0110 for (;;) {
0111 if (!kbd_pending())
0112 break;
0113 getchar();
0114 }
0115 }
0116
0117 int getchar_timeout(void)
0118 {
0119 int cnt = 30;
0120 int t0, t1;
0121
0122 t0 = gettime();
0123
0124 while (cnt) {
0125 if (kbd_pending())
0126 return getchar();
0127
0128 t1 = gettime();
0129 if (t0 != t1) {
0130 cnt--;
0131 t0 = t1;
0132 }
0133 }
0134
0135 return 0;
0136 }
0137