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$"); 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 SECOND 18 /* Circa that many ticks in a second. */ 31 32uint8_t ioctrl = IO_KEYBOARD; 33 34void 35putc(int c) 36{ 37 38 v86.ctl = V86_FLAGS; 39 v86.addr = 0x10; 40 v86.eax = 0xe00 | (c & 0xff); 41 v86.ebx = 0x7; 42 v86int(); 43} 44 45void 46xputc(int c) 47{ 48 49 if (ioctrl & IO_KEYBOARD) 50 putc(c); 51 if (ioctrl & IO_SERIAL) 52 sio_putc(c); 53} 54 55void 56putchar(int c) 57{ 58 59 if (c == '\n') 60 xputc('\r'); 61 xputc(c); 62} 63 64int 65getc(int fn) 66{ 67 68 /* 69 * The extra comparison against zero is an attempt to work around 70 * what appears to be a bug in QEMU and Bochs. Both emulators 71 * sometimes report a key-press with scancode one and ascii zero 72 * when no such key is pressed in reality. As far as I can tell, 73 * this only happens shortly after a reboot. 74 */ 75 v86.ctl = V86_FLAGS; 76 v86.addr = 0x16; 77 v86.eax = fn << 8; 78 v86int(); 79 return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff)); 80} 81 82int 83xgetc(int fn) 84{ 85 86 if (OPT_CHECK(RBX_NOINTR)) 87 return (0); 88 for (;;) { 89 if (ioctrl & IO_KEYBOARD && getc(1)) 90 return (fn ? 1 : getc(0)); 91 if (ioctrl & IO_SERIAL && sio_ischar()) 92 return (fn ? 1 : sio_getc()); 93 if (fn) 94 return (0); 95 } 96 /* NOTREACHED */ 97} 98 99int 100keyhit(unsigned int secs) 101{ 102 uint32_t t0, t1; 103 104 if (OPT_CHECK(RBX_NOINTR)) 105 return (0); 106 secs *= SECOND; 107 t0 = 0; 108 for (;;) { 109 if (xgetc(1)) 110 return (1); 111 if (secs > 0) { 112 t1 = *(uint32_t *)PTOV(0x46c); 113 if (!t0) 114 t0 = t1; 115 if (t1 < t0 || t1 >= t0 + secs) 116 return (0); 117 } 118 } 119 /* NOTREACHED */ 120} 121 122void 123getstr(char *cmdstr, size_t cmdstrsize) 124{ 125 char *s; 126 int c; 127 128 s = cmdstr; 129 for (;;) { 130 switch (c = xgetc(0)) { 131 case 0: 132 break; 133 case '\177': 134 case '\b': 135 if (s > cmdstr) { 136 s--; 137 printf("\b \b"); 138 } 139 break; 140 case '\n': 141 case '\r': 142 *s = 0; 143 return; 144 default: 145 if (s - cmdstr < cmdstrsize - 1) 146 *s++ = c; 147 putchar(c); 148 break; 149 } 150 } 151} 152