tape-kernel 1.0
a modular modern independent kernel
Loading...
Searching...
No Matches
kb.c
Go to the documentation of this file.
1//kb.c -- keyboard functions (raw)
2#include "../lib/types.h"
3#include "kb.h"
4#include "io.h"
5
7static uint8_t caps_lock = 0;
8
9/**
10 * @brief scntasci converts a keyboard scancode to an ascii character
11 *
12 * scntasci is a function that translates ps/2 scancodes into ascii
13 * characters, applying shift and caps lock state for proper casing
14 * @param inpt, the raw scancode byte from the keyboard
15 * @param shifted, whether shift is currently pressed (1) or not (0)
16 *
17 * using scntasci is done with
18 * @code{.c}
19 * #include "../io/kb.h" //or just kb.h
20 * uint8_t scancode = inb(0x60);
21 * uint8_t ascii = scntasci(scancode, 0); //convert without shift
22 * @endcode
23 *
24 * @see gtchr(), kbstate()
25 */
27 //handle extended keys (0xE0 prefix)
28 //for now, just return 0 for extended keys
29
30 //normal keys with shift/caps mapping
31 switch (inpt) {
32 //letters (a-z)
33 case 0x1E: return (shifted ^ caps_lock) ? 'A' : 'a';
34 case 0x30: return (shifted ^ caps_lock) ? 'B' : 'b';
35 case 0x2E: return (shifted ^ caps_lock) ? 'C' : 'c';
36 case 0x20: return (shifted ^ caps_lock) ? 'D' : 'd';
37 case 0x12: return (shifted ^ caps_lock) ? 'E' : 'e';
38 case 0x21: return (shifted ^ caps_lock) ? 'F' : 'f';
39 case 0x22: return (shifted ^ caps_lock) ? 'G' : 'g';
40 case 0x23: return (shifted ^ caps_lock) ? 'H' : 'h';
41 case 0x17: return (shifted ^ caps_lock) ? 'I' : 'i';
42 case 0x24: return (shifted ^ caps_lock) ? 'J' : 'j';
43 case 0x25: return (shifted ^ caps_lock) ? 'K' : 'k';
44 case 0x26: return (shifted ^ caps_lock) ? 'L' : 'l';
45 case 0x32: return (shifted ^ caps_lock) ? 'M' : 'm';
46 case 0x31: return (shifted ^ caps_lock) ? 'N' : 'n';
47 case 0x18: return (shifted ^ caps_lock) ? 'O' : 'o';
48 case 0x19: return (shifted ^ caps_lock) ? 'P' : 'p';
49 case 0x10: return (shifted ^ caps_lock) ? 'Q' : 'q';
50 case 0x13: return (shifted ^ caps_lock) ? 'R' : 'r';
51 case 0x1F: return (shifted ^ caps_lock) ? 'S' : 's';
52 case 0x14: return (shifted ^ caps_lock) ? 'T' : 't';
53 case 0x16: return (shifted ^ caps_lock) ? 'U' : 'u';
54 case 0x2F: return (shifted ^ caps_lock) ? 'V' : 'v';
55 case 0x11: return (shifted ^ caps_lock) ? 'W' : 'w';
56 case 0x2D: return (shifted ^ caps_lock) ? 'X' : 'x';
57 case 0x15: return (shifted ^ caps_lock) ? 'Y' : 'y';
58 case 0x2C: return (shifted ^ caps_lock) ? 'Z' : 'z';
59
60 //numbers (row above letters)
61 case 0x02: return shifted ? '!' : '1';
62 case 0x03: return shifted ? '@' : '2';
63 case 0x04: return shifted ? '#' : '3';
64 case 0x05: return shifted ? '$' : '4';
65 case 0x06: return shifted ? '%' : '5';
66 case 0x07: return shifted ? '^' : '6';
67 case 0x08: return shifted ? '&' : '7';
68 case 0x09: return shifted ? '*' : '8';
69 case 0x0A: return shifted ? '(' : '9';
70 case 0x0B: return shifted ? ')' : '0';
71
72 //symbols
73 case 0x0C: return shifted ? '_' : '-'; //- and _
74 case 0x0D: return shifted ? '+' : '='; //= and +
75 case 0x1A: return shifted ? '{' : '['; //[ and {
76 case 0x1B: return shifted ? '}' : ']'; //] and }
77 case 0x2B: return shifted ? '|' : '\\'; //\ and |
78 case 0x27: return shifted ? ':' : ';'; //; and :
79 case 0x28: return shifted ? '"' : '\''; //' and "
80 case 0x29: return shifted ? '~' : '`'; //` and ~
81 case 0x33: return shifted ? '<' : ','; //, and <
82 case 0x34: return shifted ? '>' : '.'; //. and >
83 case 0x35: return shifted ? '?' : '/'; //'/' and ?
84 case 0x39: return ' '; //space (no shift)
85
86 //special keys
87 case 0x1C: return '\n'; //enter
88 case 0x0E: return '\b'; //backspace
89 case 0x0F: return '\t'; //tab
90
91 default: return 0;
92 }
93}
94
95/**
96 * @brief listens for a character outside of loops from ports
97 *
98 * gtchr is a function that directly gets a key pressed from outside of rdln or loops
99 *
100 * use of gtchr is done with
101 * @code{.c}
102 * #include "../io/kb.h" //or just kb.h
103 * uint8_t key = gtchr(); //also often times in a while(1) loop
104 * if (key == 'e') { do something };
105 * @endcode
106 *
107 * @see rdln()
108*/
110 while(1) {
111 uint8_t inpt = inb(0x60); //read scancode
112
113 //handle extended scancode prefix (0xE0)
114 if (inpt == 0xE0) {
115 uint8_t ext = inb(0x60); //read extended scancode
116 //extended keys, arrows, home, end, etc
117 //for now, ignore them
118 while (inb(0x60) != ext + 0x80) {
119 //wait for release
120 }
121 continue;
122 }
123
124 //check for shift key presses/releases
125 if (inpt == 0x2A || inpt == 0x36) {
126 //left or right shift pressed
127 shift_pressed = 1;
128 continue;
129 }
130 if (inpt == 0xAA || inpt == 0xB6) {
131 //left or right shift released
132 shift_pressed = 0;
133 continue;
134 }
135
136 //check for caps Lock
137 if (inpt == 0x3A) {
138 //caps lock pressed
140 //wait for release
141 while (inb(0x60) != 0xBA) {
142 //wait
143 }
144 continue;
145 }
146
147 //key release (scancode >= 0x80)
148 if (inpt >= 0x80) {
149 continue; //skip release codes
150 }
151
152 //convert to ascii with current shift state
153 uint8_t shifted = (shift_pressed == 1);
154 uint8_t asci = scntasci(inpt, shifted);
155
156 //wait for key release
157 while (inb(0x60) != inpt + 0x80) {
158 //wait
159 }
160
161 if (asci != 0) {
162 return asci;
163 }
164 }
165}
166
167/**
168 * @brief kbstate exports the current keyboard modifier state
169 *
170 * kbstate is a function that writes the current shift and caps lock
171 * states into the provided pointers
172 * @param shift, a pointer to store the shift state (1 = pressed)
173 * @param caps, a pointer to store the caps lock state (1 = enabled)
174 *
175 * using kbstate is done with
176 * @code{.c}
177 * #include "../io/kb.h" //or just kb.h
178 * uint8_t shift, caps;
179 * kbstate(&shift, &caps);
180 * @endcode
181 *
182 * @see kbreset(), gtchr()
183 */
184void __kbstate(uint8_t *shift, uint8_t *caps) {
185 if (shift) *shift = shift_pressed;
186 if (caps) *caps = caps_lock;
187}
188
189/**
190 * @brief kbreset resets the keyboard modifier states
191 *
192 * kbreset is a function that clears the shift and caps lock states
193 * back to their defaults (both off)
194 *
195 * using kbreset is done with
196 * @code{.c}
197 * #include "../io/kb.h" //or just kb.h
198 * kbreset();
199 * @endcode
200 *
201 * @see kbstate(), gtchr()
202 */
203void __kbreset(void) {
204 shift_pressed = 0;
205 caps_lock = 0;
206}
#define inb
Definition io.h:6
uint8_t __scntasci(uint8_t inpt, uint8_t shifted)
scntasci converts a keyboard scancode to an ascii character
Definition kb.c:26
static uint8_t shift_pressed
Definition kb.c:6
void __kbstate(uint8_t *shift, uint8_t *caps)
kbstate exports the current keyboard modifier state
Definition kb.c:184
void __kbreset(void)
kbreset resets the keyboard modifier states
Definition kb.c:203
static uint8_t caps_lock
Definition kb.c:7
uint8_t __gtchr(void)
listens for a character outside of loops from ports
Definition kb.c:109
#define scntasci
Definition kb.h:7
unsigned char uint8_t
Definition types.h:28