1ca987d46SWarner Losh /*- 2ca987d46SWarner Losh * Copyright (c) 1998 Robert Nordier 3ca987d46SWarner Losh * All rights reserved. 4ca987d46SWarner Losh * 5ca987d46SWarner Losh * Redistribution and use in source and binary forms are freely 6ca987d46SWarner Losh * permitted provided that the above copyright notice and this 7ca987d46SWarner Losh * paragraph and the following disclaimer are duplicated in all 8ca987d46SWarner Losh * such forms. 9ca987d46SWarner Losh * 10ca987d46SWarner Losh * This software is provided "AS IS" and without any express or 11ca987d46SWarner Losh * implied warranties, including, without limitation, the implied 12ca987d46SWarner Losh * warranties of merchantability and fitness for a particular 13ca987d46SWarner Losh * purpose. 14ca987d46SWarner Losh */ 15ca987d46SWarner Losh 16ca987d46SWarner Losh #include <sys/cdefs.h> 17ca987d46SWarner Losh __FBSDID("$FreeBSD$"); 18ca987d46SWarner Losh 19ca987d46SWarner Losh #include <sys/param.h> 20ca987d46SWarner Losh 21ca987d46SWarner Losh #include <machine/psl.h> 22ca987d46SWarner Losh 23ca987d46SWarner Losh #include <btxv86.h> 24ca987d46SWarner Losh 2565628439SWarner Losh #include "stand.h" 2665628439SWarner Losh 27ca987d46SWarner Losh #include "lib.h" 28ca987d46SWarner Losh #include "rbx.h" 29ca987d46SWarner Losh #include "cons.h" 30ca987d46SWarner Losh 31ca987d46SWarner Losh #define SECOND 18 /* Circa that many ticks in a second. */ 32ca987d46SWarner Losh 33ca987d46SWarner Losh uint8_t ioctrl = IO_KEYBOARD; 34ca987d46SWarner Losh 35ca987d46SWarner Losh void 36ca987d46SWarner Losh putc(int c) 37ca987d46SWarner Losh { 38ca987d46SWarner Losh 39ca987d46SWarner Losh v86.ctl = V86_FLAGS; 40ca987d46SWarner Losh v86.addr = 0x10; 41ca987d46SWarner Losh v86.eax = 0xe00 | (c & 0xff); 42ca987d46SWarner Losh v86.ebx = 0x7; 43ca987d46SWarner Losh v86int(); 44ca987d46SWarner Losh } 45ca987d46SWarner Losh 46ca987d46SWarner Losh void 47ca987d46SWarner Losh xputc(int c) 48ca987d46SWarner Losh { 49ca987d46SWarner Losh 50ca987d46SWarner Losh if (ioctrl & IO_KEYBOARD) 51ca987d46SWarner Losh putc(c); 52ca987d46SWarner Losh if (ioctrl & IO_SERIAL) 53ca987d46SWarner Losh sio_putc(c); 54ca987d46SWarner Losh } 55ca987d46SWarner Losh 566469d2b4SToomas Soome static void 576469d2b4SToomas Soome getcursor(int *row, int *col) 586469d2b4SToomas Soome { 596469d2b4SToomas Soome v86.ctl = V86_FLAGS; 606469d2b4SToomas Soome v86.addr = 0x10; 616469d2b4SToomas Soome v86.eax = 0x300; 626469d2b4SToomas Soome v86.ebx = 0x7; 636469d2b4SToomas Soome v86int(); 646469d2b4SToomas Soome 656469d2b4SToomas Soome if (row != NULL) 666469d2b4SToomas Soome *row = v86.edx >> 8; 676469d2b4SToomas Soome if (col != NULL) 686469d2b4SToomas Soome *col = v86.edx & 0xff; 696469d2b4SToomas Soome } 706469d2b4SToomas Soome 71ca987d46SWarner Losh void 72ca987d46SWarner Losh putchar(int c) 73ca987d46SWarner Losh { 746469d2b4SToomas Soome int i, col; 75ca987d46SWarner Losh 766469d2b4SToomas Soome switch (c) { 776469d2b4SToomas Soome case '\n': 78ca987d46SWarner Losh xputc('\r'); 796469d2b4SToomas Soome break; 806469d2b4SToomas Soome case '\t': 816469d2b4SToomas Soome col = 0; 826469d2b4SToomas Soome getcursor(NULL, &col); 836469d2b4SToomas Soome col = 8 - (col % 8); 846469d2b4SToomas Soome for (i = 0; i < col; i++) 856469d2b4SToomas Soome xputc(' '); 866469d2b4SToomas Soome return; 876469d2b4SToomas Soome } 88ca987d46SWarner Losh xputc(c); 89ca987d46SWarner Losh } 90ca987d46SWarner Losh 91ca987d46SWarner Losh int 92ca987d46SWarner Losh getc(int fn) 93ca987d46SWarner Losh { 94ca987d46SWarner Losh 95ca987d46SWarner Losh v86.ctl = V86_FLAGS; 96ca987d46SWarner Losh v86.addr = 0x16; 97ca987d46SWarner Losh v86.eax = fn << 8; 98ca987d46SWarner Losh v86int(); 99ca987d46SWarner Losh 100ca987d46SWarner Losh if (fn == 0) 101ca987d46SWarner Losh return (v86.eax); 102ca987d46SWarner Losh 103ca987d46SWarner Losh if (V86_ZR(v86.efl)) 104ca987d46SWarner Losh return (0); 105ca987d46SWarner Losh return (v86.eax); 106ca987d46SWarner Losh } 107ca987d46SWarner Losh 108ca987d46SWarner Losh int 109ca987d46SWarner Losh xgetc(int fn) 110ca987d46SWarner Losh { 111ca987d46SWarner Losh 112ca987d46SWarner Losh if (OPT_CHECK(RBX_NOINTR)) 113ca987d46SWarner Losh return (0); 114ca987d46SWarner Losh for (;;) { 115ca987d46SWarner Losh if (ioctrl & IO_KEYBOARD && getc(1)) 116ca987d46SWarner Losh return (fn ? 1 : getc(0)); 117ca987d46SWarner Losh if (ioctrl & IO_SERIAL && sio_ischar()) 118ca987d46SWarner Losh return (fn ? 1 : sio_getc()); 119ca987d46SWarner Losh if (fn) 120ca987d46SWarner Losh return (0); 121ca987d46SWarner Losh } 122ca987d46SWarner Losh /* NOTREACHED */ 123ca987d46SWarner Losh } 124ca987d46SWarner Losh 125ca987d46SWarner Losh int 126ca987d46SWarner Losh getchar(void) 127ca987d46SWarner Losh { 128ca987d46SWarner Losh 1296469d2b4SToomas Soome return (xgetc(0) & 0xff); 130ca987d46SWarner Losh } 131ca987d46SWarner Losh 132ca987d46SWarner Losh int 133ca987d46SWarner Losh keyhit(unsigned int secs) 134ca987d46SWarner Losh { 135ca987d46SWarner Losh uint32_t t0, t1, c; 136ca987d46SWarner Losh 137ca987d46SWarner Losh if (OPT_CHECK(RBX_NOINTR)) 138ca987d46SWarner Losh return (0); 139ca987d46SWarner Losh secs *= SECOND; 140ca987d46SWarner Losh t0 = 0; 141ca987d46SWarner Losh for (;;) { 142ca987d46SWarner Losh /* 143ca987d46SWarner Losh * The extra comparison is an attempt to work around 144ca987d46SWarner Losh * what appears to be a bug in QEMU and Bochs. Both emulators 145ca987d46SWarner Losh * sometimes report a key-press with scancode one and ascii zero 146ca987d46SWarner Losh * when no such key is pressed in reality. As far as I can tell, 147ca987d46SWarner Losh * this only happens shortly after a reboot. 148ca987d46SWarner Losh */ 149ca987d46SWarner Losh c = xgetc(1); 150ca987d46SWarner Losh if (c != 0 && c != 0x0100) 151ca987d46SWarner Losh return (1); 152ca987d46SWarner Losh if (secs > 0) { 153ca987d46SWarner Losh t1 = *(uint32_t *)PTOV(0x46c); 154ca987d46SWarner Losh if (!t0) 155ca987d46SWarner Losh t0 = t1; 156ca987d46SWarner Losh if (t1 < t0 || t1 >= t0 + secs) 157ca987d46SWarner Losh return (0); 158ca987d46SWarner Losh } 159ca987d46SWarner Losh } 160ca987d46SWarner Losh /* NOTREACHED */ 161ca987d46SWarner Losh } 162ca987d46SWarner Losh 163ca987d46SWarner Losh void 164ca987d46SWarner Losh getstr(char *cmdstr, size_t cmdstrsize) 165ca987d46SWarner Losh { 166ca987d46SWarner Losh char *s; 167ca987d46SWarner Losh int c; 168ca987d46SWarner Losh 169ca987d46SWarner Losh s = cmdstr; 170ca987d46SWarner Losh for (;;) { 171ca987d46SWarner Losh c = xgetc(0); 172ca987d46SWarner Losh 173ca987d46SWarner Losh /* Translate some extended codes. */ 174ca987d46SWarner Losh switch (c) { 175ca987d46SWarner Losh case 0x5300: /* delete */ 176ca987d46SWarner Losh c = '\177'; 177ca987d46SWarner Losh break; 178ca987d46SWarner Losh default: 179ca987d46SWarner Losh c &= 0xff; 180ca987d46SWarner Losh break; 181ca987d46SWarner Losh } 182ca987d46SWarner Losh 183ca987d46SWarner Losh switch (c) { 184ca987d46SWarner Losh case '\177': 185ca987d46SWarner Losh case '\b': 186ca987d46SWarner Losh if (s > cmdstr) { 187ca987d46SWarner Losh s--; 188ca987d46SWarner Losh printf("\b \b"); 189ca987d46SWarner Losh } 190ca987d46SWarner Losh break; 191ca987d46SWarner Losh case '\n': 192ca987d46SWarner Losh case '\r': 193ca987d46SWarner Losh *s = 0; 194ca987d46SWarner Losh return; 195ca987d46SWarner Losh default: 196ca987d46SWarner Losh if (c >= 0x20 && c <= 0x7e) { 197ca987d46SWarner Losh if (s - cmdstr < cmdstrsize - 1) 198ca987d46SWarner Losh *s++ = c; 199ca987d46SWarner Losh putchar(c); 200ca987d46SWarner Losh } 201ca987d46SWarner Losh break; 202ca987d46SWarner Losh } 203ca987d46SWarner Losh } 204ca987d46SWarner Losh } 205