cons.c revision 213136
1/*- 2 * Copyright (c) 1998 Robert Nordier 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are freely 6 * permitted provided that the above copyright notice and this 7 * paragraph and the following disclaimer are duplicated in all 8 * such forms. 9 * 10 * This software is provided "AS IS" and without any express or 11 * implied warranties, including, without limitation, the implied 12 * warranties of merchantability and fitness for a particular 13 * purpose. 14 */ 15 16#include <sys/cdefs.h> 17__FBSDID("$FreeBSD: head/sys/boot/i386/common/cons.c 213136 2010-09-24 19:49:12Z pjd $"); 18 19#include <sys/param.h> 20 21#include <machine/psl.h> 22 23#include <btxv86.h> 24 25#include "lib.h" 26#include "rbx.h" 27#include "util.h" 28#include "cons.h" 29 30#define V86_ZR(x) ((x) & PSL_Z) 31 32#define SECOND 18 /* Circa that many ticks in a second. */ 33 34uint8_t ioctrl = IO_KEYBOARD; 35 36void 37putc(int c) 38{ 39 40 v86.addr = 0x10; 41 v86.eax = 0xe00 | (c & 0xff); 42 v86.ebx = 0x7; 43 v86int(); 44} 45 46void 47xputc(int c) 48{ 49 50 if (ioctrl & IO_KEYBOARD) 51 putc(c); 52 if (ioctrl & IO_SERIAL) 53 sio_putc(c); 54} 55 56void 57putchar(int c) 58{ 59 60 if (c == '\n') 61 xputc('\r'); 62 xputc(c); 63} 64 65int 66getc(int fn) 67{ 68 69 /* 70 * The extra comparison against zero is an attempt to work around 71 * what appears to be a bug in QEMU and Bochs. Both emulators 72 * sometimes report a key-press with scancode one and ascii zero 73 * when no such key is pressed in reality. As far as I can tell, 74 * this only happens shortly after a reboot. 75 */ 76 v86.ctl = V86_FLAGS; 77 v86.addr = 0x16; 78 v86.eax = fn << 8; 79 v86int(); 80 return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff)); 81} 82 83int 84xgetc(int fn) 85{ 86 87 if (OPT_CHECK(RBX_NOINTR)) 88 return (0); 89 for (;;) { 90 if (ioctrl & IO_KEYBOARD && getc(1)) 91 return (fn ? 1 : getc(0)); 92 if (ioctrl & IO_SERIAL && sio_ischar()) 93 return (fn ? 1 : sio_getc()); 94 if (fn) 95 return (0); 96 } 97 /* NOTREACHED */ 98} 99 100int 101keyhit(unsigned int secs) 102{ 103 uint32_t t0, t1; 104 105 if (OPT_CHECK(RBX_NOINTR)) 106 return (0); 107 secs *= SECOND; 108 t0 = 0; 109 for (;;) { 110 if (xgetc(1)) 111 return (1); 112 if (secs > 0) { 113 t1 = *(uint32_t *)PTOV(0x46c); 114 if (!t0) 115 t0 = t1; 116 if (t1 < t0 || t1 >= t0 + secs) 117 return (0); 118 } 119 } 120 /* NOTREACHED */ 121} 122 123void 124getstr(char *cmdstr, size_t cmdstrsize) 125{ 126 char *s; 127 int c; 128 129 s = cmdstr; 130 for (;;) { 131 switch (c = xgetc(0)) { 132 case 0: 133 break; 134 case '\177': 135 case '\b': 136 if (s > cmdstr) { 137 s--; 138 printf("\b \b"); 139 } 140 break; 141 case '\n': 142 case '\r': 143 *s = 0; 144 return; 145 default: 146 if (s - cmdstr < cmdstrsize - 1) 147 *s++ = c; 148 putchar(c); 149 break; 150 } 151 } 152} 153