/* * Read 1 character from keyboard's data port. * * If there are no characters available in keyboard buffer, the function * will block until interrupt arrives (possible race condition...). */ u8_t __read_raw_kbd_char(void) { u8_t c; while (1) { // Fetch a single character from keyboard c = *kbd_mmio_address; // No data available? Idle until there are some chars to read. if (c == 0xFF) { __idle(); continue; } return c; } }
char bios_getchar(char *hi) { com32sys_t ireg, oreg; unsigned char data; memset(&ireg, 0, sizeof(ireg)); memset(&oreg, 0, sizeof(oreg)); while (1) { __idle(); ireg.eax.b[1] = 0x11; /* Poll keyboard */ __intcall(0x16, &ireg, &oreg); if (oreg.eflags.l & EFLAGS_ZF) { if (!SerialPort) continue; cli(); if (SerialTail != SerialHead) { /* serial queued */ sti(); /* We already know we'll consume data */ data = *SerialTail++; if (SerialTail > SerialHead + serial_buf_size) SerialTail = SerialHead; } else { /* LSR */ data = inb(SerialPort + 5) & 1; if (!data) { sti(); continue; } data = inb(SerialPort + 6); data &= FlowIgnore; if (data != FlowIgnore) { sti(); continue; } data = inb(SerialPort); sti(); break; } } else { /* Keyboard input? */ ireg.eax.b[1] = 0x10; /* Get keyboard input */ __intcall(0x16, &ireg, &oreg); data = oreg.eax.b[0]; *hi = oreg.eax.b[1]; if (data == 0xE0) data = 0; if (data) { /* Convert character sets */ data = KbdMap[data]; } } break; } reset_idle(); /* Character received */ return data; }