Ми повертаємось до серії навчальних посібників про те, як створити власну операційну систему. Думаю, ця глава вам дуже сподобається, тому що ми нарешті можемо взаємодіяти з нашою операційною системою. Сьогодні ми прочитаємо введення з клавіатури. Для цього схема схожа на схему таймера. Ми все одно повинні використовувати IRQ, тому почнемо так само, як із таймером.
ND_IRQ_InstallHandler (1, & ND_Keyboard_Handler);
Однак наш обробник клавіатури дещо складніший, оскільки ми читаємо клавіші та вкладаємо їх у буфер.
extern "C" void ND_Keyboard_Handler (struct regs * r) {unsigned char scancode = ND :: Keyboard :: GetChar (); if (scancode! = 255) {ND :: Screen :: PutChar (scancode); stringBuffer [stringPos] = код сканування; stringPos ++; }}
http://gist.github.com/634afddcb3e977ea202d
Ми можемо перевірити, як ми викликаємо функцію під назвою ND :: Keyboard :: GetChar. Там ми отримуємо символ, а потім, якщо це не порожній символ (тут я використав 255, нам довелося б використовувати кращу систему), ми поміщаємо символ на екран і зберігаємо його у простому буфері символів (це за умови вдосконалення, поточна система може переповнитися).
nsigned char ND :: Keyboard :: GetChar () {непідписаний код сканування char; scancode = (без підписаного символу) ND :: Ports :: InputB (0x60); if (scancode & ND_KEYBOARD_KEY_RELEASE) {return 255; } else {повернути en_US [код сканування]; }} char * ND :: Keyboard :: GetString () {while (stringBuffer [stringPos-1]! = '\ n') {} stringPos = 0; повернути stringBuffer; }
http://gist.github.com/2d4f13e0b1a281c66884
Тут ми бачимо, як отримується натиснута клавіша. При 0x60 завжди буде натиснута остання клавіша. Насправді його можна прочитати безпосередньо, не використовуючи IRQ, але тоді ми не знатимемо, як визначити, коли відбулася зміна. Там ми перевіряємо за допомогою операції І, що отриманий нами код відповідає клавіші, яку було припинено натисканням.
У цьому випадку ми повертаємо 255 (оскільки тоді ми будемо ігнорувати це), інакше клавіша була натиснута. У цьому випадку ми повертаємо позицію масиву, який називається en_US. Яку інформацію містить цей масив? Цей масив - це те, що ми називали б клавіатурою або картою символів. Як відомо, різні мови мають різні клавіатури і не підтримуються, оскільки вони перезаписують клавіші. Отже, en_US дасть нам ключ, відповідний кожному коду, і він буде працювати на американській клавіатурі.
непідписаний знак en_US [128] = {0,27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0 ',' - ',' = ',' \ b ',' \ t ',' q ',' w ',' e ',' r ',' t ',' y ',' u ',' i ',' o ',' p ',' [','] ',' \ n ', 0, / * Ctrl * /' a ',' s ',' d ',' f ',' g ', 'h', 'j', 'k', 'l', ';', '\' ',' '', 0, / * Лівий зсув * / '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, / * Зсув вправо * / '*', 0, / * Alt * / '', 0, / * Caps lock * / 0,0,0,0,0,0,0,0,0,0, / * Клавіші F1-F10 * / 0, / * Num lock * / 0, / * Блокування прокрутки * / 0, / * Клавіша головного * / 0, / * Стрілка вгору * / 0, / * Сторінка вгору * / '-', 0, / * Стрілка вліво * / 0, 0, / * Стрілка вправо * / '+', 0, / * Клавіша завершення * / 0, / * Стрілка вниз * / 0, / * Сторінка вниз * / 0, / * Клавіша вставки * / 0, / * Клавіша видалення * / 0,0,0, 0, 0, 11, / * Клавіші F12-F0 * / XNUMX};
http://gist.github.com/bf52085aec05f3070b65
Також була визначена функція, яка отримала фразу. Мета полягає в тому, щоб просто полегшити доступ до рядків із програм, які цього потребують, на даний момент лише одного. Я говорю про NextShellLite, зменшену версію можливої майбутньої оболонки, яку мав би NextDivel. Призначення NextShellLite полягає лише у забезпеченні зменшеної оболонки для поступового тестування нових функціональних можливостей. Я не збираюся розміщувати тут код оболонки, але я включив його до коду NextDivel.
На даний момент він працює не як окрема програма, а як функція, що викликається ядром, головним чином тому, що ми ще не додали опцію для запуску виконуваних файлів. І звичайно, кілька фотографій того, як працює оболонка з новими функціями введення з клавіатури.