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