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/>.
26 /* table with rough translations from set 1 scancodes to ASCII-ish */
27 static int scantbl[] = {
28 0, KB_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', /* 0 - e */
29 '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* f - 1c */
30 KB_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', /* 1d - 29 */
31 KB_LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', KB_RSHIFT, /* 2a - 36 */
32 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 */
33 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 */
34 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 */
35 0, 0, 0, 0, 0, 0, 0, /* 59 - 5f */
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6f */
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 70 - 7f */
43 #define ADVANCE(x) ((x) = ((x) + 1) & (BUFSZ - 1))
45 static int buffer[BUFSZ];
46 static int buf_ridx, buf_widx;
48 static unsigned int num_pressed;
49 static unsigned char keystate[256];
53 buf_ridx = buf_widx = 0;
55 memset(keystate, 0, sizeof keystate);
57 interrupt(IRQ_TO_INTR(KB_IRQ), kbintr);
60 int kb_isdown(int key)
67 return keystate[KB_LALT] + keystate[KB_RALT];
70 return keystate[KB_LCTRL] + keystate[KB_RCTRL];
78 while((key = kb_getkey()) == -1) {
79 /* put the processor to sleep while waiting for keypresses, but first
80 * make sure interrupts are enabled, or we'll sleep forever
92 if(buf_ridx == buf_widx) {
95 res = buffer[buf_ridx];
100 void kb_putback(int key)
102 /* go back a place */
107 /* if the write end hasn't caught up with us, go back one place
108 * and put it there, otherwise just overwrite the oldest key which
109 * is right where we were.
111 if(buf_ridx == buf_widx) {
115 buffer[buf_ridx] = key;
118 int kb_wait_write(void)
121 for(i=0; i<32768; i++) {
122 if(!(inb(KB_STATUS_PORT) & KB_STAT_INBUF_FULL)) {
127 /*printf("kb_wait_write timeout\n");*/
131 int kb_wait_read(void)
134 for(i=0; i<32768; i++) {
135 if((inb(KB_STATUS_PORT) & KB_STAT_OUTBUF_FULL)) {
140 /*printf("kb_wait_read timeout\n");*/
144 void kb_send_cmd(unsigned char cmd)
147 outb(cmd, KB_CMD_PORT);
150 void kb_send_data(unsigned char data)
153 outb(data, KB_DATA_PORT);
156 unsigned char kb_read_data(void)
159 return inb(KB_DATA_PORT);
167 code = inb(KB_DATA_PORT);
173 if(num_pressed > 0) {
185 /* append to buffer */
186 buffer[buf_widx] = key;
188 /* if the write end overtook the read end, advance the read end
189 * too, to discard the oldest keypress from the buffer
191 if(buf_widx == buf_ridx) {
196 /* and update keystate table */
197 keystate[key] = press;