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