1213136Spjd/*- 2213136Spjd * Copyright (c) 1998 Robert Nordier 3213136Spjd * All rights reserved. 4213136Spjd * 5213136Spjd * Redistribution and use in source and binary forms are freely 6213136Spjd * permitted provided that the above copyright notice and this 7213136Spjd * paragraph and the following disclaimer are duplicated in all 8213136Spjd * such forms. 9213136Spjd * 10213136Spjd * This software is provided "AS IS" and without any express or 11213136Spjd * implied warranties, including, without limitation, the implied 12213136Spjd * warranties of merchantability and fitness for a particular 13213136Spjd * purpose. 14213136Spjd */ 15213136Spjd 16213136Spjd#include <sys/cdefs.h> 17213136Spjd__FBSDID("$FreeBSD$"); 18213136Spjd 19213136Spjd#include <sys/param.h> 20213136Spjd 21213136Spjd#include <machine/psl.h> 22213136Spjd 23213136Spjd#include <btxv86.h> 24213136Spjd 25213136Spjd#include "lib.h" 26213136Spjd#include "rbx.h" 27213136Spjd#include "util.h" 28213136Spjd#include "cons.h" 29213136Spjd 30213136Spjd#define SECOND 18 /* Circa that many ticks in a second. */ 31213136Spjd 32213136Spjduint8_t ioctrl = IO_KEYBOARD; 33213136Spjd 34213136Spjdvoid 35213136Spjdputc(int c) 36213136Spjd{ 37213136Spjd 38219702Sae v86.ctl = V86_FLAGS; 39213136Spjd v86.addr = 0x10; 40213136Spjd v86.eax = 0xe00 | (c & 0xff); 41213136Spjd v86.ebx = 0x7; 42213136Spjd v86int(); 43213136Spjd} 44213136Spjd 45213136Spjdvoid 46213136Spjdxputc(int c) 47213136Spjd{ 48213136Spjd 49213136Spjd if (ioctrl & IO_KEYBOARD) 50213136Spjd putc(c); 51213136Spjd if (ioctrl & IO_SERIAL) 52213136Spjd sio_putc(c); 53213136Spjd} 54213136Spjd 55213136Spjdvoid 56213136Spjdputchar(int c) 57213136Spjd{ 58213136Spjd 59213136Spjd if (c == '\n') 60213136Spjd xputc('\r'); 61213136Spjd xputc(c); 62213136Spjd} 63213136Spjd 64213136Spjdint 65213136Spjdgetc(int fn) 66213136Spjd{ 67213136Spjd 68213136Spjd /* 69213136Spjd * The extra comparison against zero is an attempt to work around 70213136Spjd * what appears to be a bug in QEMU and Bochs. Both emulators 71213136Spjd * sometimes report a key-press with scancode one and ascii zero 72213136Spjd * when no such key is pressed in reality. As far as I can tell, 73213136Spjd * this only happens shortly after a reboot. 74213136Spjd */ 75213136Spjd v86.ctl = V86_FLAGS; 76213136Spjd v86.addr = 0x16; 77213136Spjd v86.eax = fn << 8; 78213136Spjd v86int(); 79213136Spjd return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff)); 80213136Spjd} 81213136Spjd 82213136Spjdint 83213136Spjdxgetc(int fn) 84213136Spjd{ 85213136Spjd 86213136Spjd if (OPT_CHECK(RBX_NOINTR)) 87213136Spjd return (0); 88213136Spjd for (;;) { 89213136Spjd if (ioctrl & IO_KEYBOARD && getc(1)) 90213136Spjd return (fn ? 1 : getc(0)); 91213136Spjd if (ioctrl & IO_SERIAL && sio_ischar()) 92213136Spjd return (fn ? 1 : sio_getc()); 93213136Spjd if (fn) 94213136Spjd return (0); 95213136Spjd } 96213136Spjd /* NOTREACHED */ 97213136Spjd} 98213136Spjd 99213136Spjdint 100213136Spjdkeyhit(unsigned int secs) 101213136Spjd{ 102213136Spjd uint32_t t0, t1; 103213136Spjd 104213136Spjd if (OPT_CHECK(RBX_NOINTR)) 105213136Spjd return (0); 106213136Spjd secs *= SECOND; 107213136Spjd t0 = 0; 108213136Spjd for (;;) { 109213136Spjd if (xgetc(1)) 110213136Spjd return (1); 111213136Spjd if (secs > 0) { 112213136Spjd t1 = *(uint32_t *)PTOV(0x46c); 113213136Spjd if (!t0) 114213136Spjd t0 = t1; 115213136Spjd if (t1 < t0 || t1 >= t0 + secs) 116213136Spjd return (0); 117213136Spjd } 118213136Spjd } 119213136Spjd /* NOTREACHED */ 120213136Spjd} 121213136Spjd 122213136Spjdvoid 123213136Spjdgetstr(char *cmdstr, size_t cmdstrsize) 124213136Spjd{ 125213136Spjd char *s; 126213136Spjd int c; 127213136Spjd 128213136Spjd s = cmdstr; 129213136Spjd for (;;) { 130213136Spjd switch (c = xgetc(0)) { 131213136Spjd case 0: 132213136Spjd break; 133213136Spjd case '\177': 134213136Spjd case '\b': 135213136Spjd if (s > cmdstr) { 136213136Spjd s--; 137213136Spjd printf("\b \b"); 138213136Spjd } 139213136Spjd break; 140213136Spjd case '\n': 141213136Spjd case '\r': 142213136Spjd *s = 0; 143213136Spjd return; 144213136Spjd default: 145213136Spjd if (s - cmdstr < cmdstrsize - 1) 146213136Spjd *s++ = c; 147213136Spjd putchar(c); 148213136Spjd break; 149213136Spjd } 150213136Spjd } 151213136Spjd} 152