2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY, without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
27 iodelay(); iodelay(); iodelay(); iodelay(); \
28 iodelay(); iodelay(); iodelay(); \
31 /* table with rough translations from set 1 scancodes to ASCII-ish */
32 static int scantbl[] = {
33 0, KB_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', /* 0 - e */
34 '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* f - 1c */
35 KB_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', /* 1d - 29 */
36 KB_LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', KB_RSHIFT, /* 2a - 36 */
37 KB_NUM_MUL, KB_LALT, ' ', KB_CAPSLK, KB_F1, KB_F2, KB_F3, KB_F4, KB_F5, KB_F6, KB_F7, KB_F8, KB_F9, KB_F10, /* 37 - 44 */
38 KB_NUMLK, KB_SCRLK, KB_NUM_7, KB_NUM_8, KB_NUM_9, KB_NUM_MINUS, KB_NUM_4, KB_NUM_5, KB_NUM_6, KB_NUM_PLUS, /* 45 - 4e */
39 KB_NUM_1, KB_NUM_2, KB_NUM_3, KB_NUM_0, KB_NUM_DOT, KB_SYSRQ, 0, 0, KB_F11, KB_F12, /* 4d - 58 */
40 0, 0, 0, 0, 0, 0, 0, /* 59 - 5f */
41 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6f */
42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 70 - 7f */
48 #define ADVANCE(x) ((x) = ((x) + 1) & (BUFSZ - 1))
50 static int buffer[BUFSZ];
51 static int buf_ridx, buf_widx;
53 static unsigned int num_pressed;
54 static unsigned char keystate[256];
58 buf_ridx = buf_widx = 0;
60 memset(keystate, 0, sizeof keystate);
62 interrupt(IRQ_TO_INTR(KB_IRQ), kbintr);
65 int kb_isdown(int key)
72 return keystate[KB_LALT] + keystate[KB_RALT];
75 return keystate[KB_LCTRL] + keystate[KB_RCTRL];
83 while((key = kb_getkey()) == -1) {
84 /* put the processor to sleep while waiting for keypresses, but first
85 * make sure interrupts are enabled, or we'll sleep forever
97 if(buf_ridx == buf_widx) {
100 res = buffer[buf_ridx];
105 void kb_putback(int key)
107 /* go back a place */
112 /* if the write end hasn't caught up with us, go back one place
113 * and put it there, otherwise just overwrite the oldest key which
114 * is right where we were.
116 if(buf_ridx == buf_widx) {
120 buffer[buf_ridx] = key;
123 int kb_wait_write(void)
126 for(i=0; i<32768; i++) {
127 if(!(inb(KB_STATUS_PORT) & KB_STAT_INBUF_FULL)) {
132 /*printf("kb_wait_write timeout\n");*/
136 int kb_wait_read(void)
139 for(i=0; i<32768; i++) {
140 if((inb(KB_STATUS_PORT) & KB_STAT_OUTBUF_FULL)) {
145 /*printf("kb_wait_read timeout\n");*/
149 void kb_send_cmd(unsigned char cmd)
152 outb(cmd, KB_CMD_PORT);
155 void kb_send_data(unsigned char data)
158 outb(data, KB_DATA_PORT);
161 unsigned char kb_read_data(void)
165 return inb(KB_DATA_PORT);
173 code = inb(KB_DATA_PORT);
179 if(num_pressed > 0) {
191 /* append to buffer */
192 buffer[buf_widx] = key;
194 /* if the write end overtook the read end, advance the read end
195 * too, to discard the oldest keypress from the buffer
197 if(buf_widx == buf_ridx) {
202 /* and update keystate table */
203 keystate[key] = press;