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