2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018-2019 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/>.
30 iodelay(); iodelay(); iodelay(); iodelay(); \
31 iodelay(); iodelay(); iodelay(); \
34 static void set_ccb(unsigned char ccb);
35 static unsigned char get_ccb(void);
40 #define ADVANCE(x) ((x) = ((x) + 1) & (BUFSZ - 1))
42 static int buffer[BUFSZ];
43 static int buf_ridx, buf_widx;
45 static unsigned int num_pressed;
46 static unsigned char keystate[256];
51 buf_ridx = buf_widx = 0;
53 memset(keystate, 0, sizeof keystate);
55 /* make sure set1 translation is enabled */
58 interrupt(IRQ_TO_INTR(KB_IRQ), kbintr);
62 void kb_intr_enable(void)
64 unsigned char ccb = get_ccb();
65 ccb |= KB_CCB_KB_INTREN;
69 void kb_intr_disable(void)
71 unsigned char ccb = get_ccb();
72 ccb &= ~KB_CCB_KB_INTREN;
76 int kb_setmode(int mode)
79 if(!kb_wait_read() || kb_read_data() != KB_ACK) {
83 if(!kb_wait_read() || kb_read_data() != KB_ACK) {
94 if(!kb_wait_read() || kb_read_data() != KB_ACK) {
98 if(!kb_wait_read() || kb_read_data() != KB_ACK) {
101 mode = kb_read_data();
113 void kb_set_translate(int xlat)
115 unsigned char ccb = get_ccb();
117 ccb |= KB_CCB_KB_XLAT;
119 ccb &= ~KB_CCB_KB_XLAT;
124 int kb_get_translate(void)
126 return get_ccb() & KB_CCB_KB_XLAT;
129 int kb_isdown(int key)
136 return keystate[KB_LALT] + keystate[KB_RALT];
139 return keystate[KB_LCTRL] + keystate[KB_RCTRL];
141 return keystate[key];
147 while((key = kb_getkey()) == -1) {
148 /* put the processor to sleep while waiting for keypresses, but first
149 * make sure interrupts are enabled, or we'll sleep forever
161 if(buf_ridx == buf_widx) {
164 res = buffer[buf_ridx];
169 void kb_putback(int key)
171 /* go back a place */
176 /* if the write end hasn't caught up with us, go back one place
177 * and put it there, otherwise just overwrite the oldest key which
178 * is right where we were.
180 if(buf_ridx == buf_widx) {
184 buffer[buf_ridx] = key;
187 int kb_wait_write(void)
190 for(i=0; i<32768; i++) {
191 if(!(inb(KB_STATUS_PORT) & KB_STAT_INBUF_FULL)) {
196 /*printf("kb_wait_write timeout\n");*/
200 int kb_wait_read(void)
203 for(i=0; i<32768; i++) {
204 if((inb(KB_STATUS_PORT) & KB_STAT_OUTBUF_FULL)) {
209 /*printf("kb_wait_read timeout\n");*/
213 void kb_send_cmd(unsigned char cmd)
216 outb(cmd, KB_CMD_PORT);
219 void kb_send_data(unsigned char data)
222 outb(data, KB_DATA_PORT);
225 unsigned char kb_read_data(void)
229 return inb(KB_DATA_PORT);
232 static void set_ccb(unsigned char ccb)
234 kb_send_cmd(KB_CMD_SET_CMDBYTE);
242 static unsigned char get_ccb(void)
244 kb_send_cmd(KB_CMD_GET_CMDBYTE);
245 return kb_read_data();
254 code = inb(KB_DATA_PORT);
265 if(num_pressed > 0) {
274 key = ext ? scantbl_set1_ext[code] : scantbl_set1[code];
278 if(key == KB_DEL && (keystate[KB_LALT] || keystate[KB_RALT]) && (keystate[KB_LCTRL] || keystate[KB_RCTRL])) {
281 /* append to buffer */
282 buffer[buf_widx] = key;
284 /* if the write end overtook the read end, advance the read end
285 * too, to discard the oldest keypress from the buffer
287 if(buf_widx == buf_ridx) {
292 /* and update keystate table */
293 keystate[key] = press;