X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=bootcensus;a=blobdiff_plain;f=src%2Fkeyb.c;fp=src%2Fkeyb.c;h=faf08a9e85ae6f5504acaa42baf9fef6fd11a901;hp=3e86f43df38445b3d3e0a2646cfc77c21a664621;hb=81c11bdd80190ec319a82b0402173cfb65fcbf72;hpb=7dcd5071e600f8cf48174d1fddb3dba57ec9476d diff --git a/src/keyb.c b/src/keyb.c index 3e86f43..faf08a9 100644 --- a/src/keyb.c +++ b/src/keyb.c @@ -1,6 +1,6 @@ /* pcboot - bootable PC demo/game kernel -Copyright (C) 2018 John Tsiombikas +Copyright (C) 2018-2019 John Tsiombikas This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ along with this program. If not, see . #include "intr.h" #include "asmops.h" #include "kbregs.h" +#include "kbscan.h" +#include "power.h" +#include "panic.h" #define delay7us() \ do { \ @@ -28,19 +31,8 @@ along with this program. If not, see . iodelay(); iodelay(); iodelay(); \ } while(0) -/* table with rough translations from set 1 scancodes to ASCII-ish */ -static int scantbl[] = { - 0, KB_ESC, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', /* 0 - e */ - '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* f - 1c */ - KB_LCTRL, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', /* 1d - 29 */ - KB_LSHIFT, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', KB_RSHIFT, /* 2a - 36 */ - 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 */ - 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 */ - 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 */ - 0, 0, 0, 0, 0, 0, 0, /* 59 - 5f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60 - 6f */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 70 - 7f */ -}; +static void set_ccb(unsigned char ccb); +static unsigned char get_ccb(void); static void kbintr(); @@ -53,13 +45,85 @@ static int buf_ridx, buf_widx; static unsigned int num_pressed; static unsigned char keystate[256]; + void kb_init(void) { buf_ridx = buf_widx = 0; num_pressed = 0; memset(keystate, 0, sizeof keystate); + /* make sure set1 translation is enabled */ + kb_set_translate(1); + interrupt(IRQ_TO_INTR(KB_IRQ), kbintr); + kb_intr_enable(); +} + +void kb_intr_enable(void) +{ + unsigned char ccb = get_ccb(); + ccb |= KB_CCB_KB_INTREN; + set_ccb(ccb); +} + +void kb_intr_disable(void) +{ + unsigned char ccb = get_ccb(); + ccb &= ~KB_CCB_KB_INTREN; + set_ccb(ccb); +} + +int kb_setmode(int mode) +{ + kb_send_data(0xf0); + if(!kb_wait_read() || kb_read_data() != KB_ACK) { + return -1; + } + kb_send_data(mode); + if(!kb_wait_read() || kb_read_data() != KB_ACK) { + return -1; + } + return 0; +} + +int kb_getmode(void) +{ + int mode; + + kb_send_data(0xf0); + if(!kb_wait_read() || kb_read_data() != KB_ACK) { + return -1; + } + kb_send_data(0); + if(!kb_wait_read() || kb_read_data() != KB_ACK) { + return -1; + } + mode = kb_read_data(); + + switch(mode) { + case 0x43: return 1; + case 0x41: return 2; + case 0x3f: return 3; + default: + break; + } + return mode; +} + +void kb_set_translate(int xlat) +{ + unsigned char ccb = get_ccb(); + if(xlat) { + ccb |= KB_CCB_KB_XLAT; + } else { + ccb &= ~KB_CCB_KB_XLAT; + } + set_ccb(ccb); +} + +int kb_get_translate(void) +{ + return get_ccb() & KB_CCB_KB_XLAT; } int kb_isdown(int key) @@ -165,16 +229,38 @@ unsigned char kb_read_data(void) return inb(KB_DATA_PORT); } +static void set_ccb(unsigned char ccb) +{ + kb_send_cmd(KB_CMD_SET_CMDBYTE); + kb_send_data(ccb); + + if(kb_wait_read()) { + kb_read_data(); + } +} + +static unsigned char get_ccb(void) +{ + kb_send_cmd(KB_CMD_GET_CMDBYTE); + return kb_read_data(); +} + static void kbintr() { unsigned char code; int key, press; + static int ext = 0; code = inb(KB_DATA_PORT); - if(code >= 128) { + if(code == 0xe0) { + ext = 1; + return; + } + + if(code & 0x80) { press = 0; - code -= 128; + code &= 0x7f; if(num_pressed > 0) { num_pressed--; @@ -185,9 +271,13 @@ static void kbintr() num_pressed++; } - key = scantbl[code]; + key = ext ? scantbl_set1_ext[code] : scantbl_set1[code]; + ext = 0; if(press) { + if(key == KB_DEL && (keystate[KB_LALT] || keystate[KB_RALT]) && (keystate[KB_LCTRL] || keystate[KB_RCTRL])) { + reboot(); + } /* append to buffer */ buffer[buf_widx] = key; ADVANCE(buf_widx);