Консультация № 55047
11.09.2006, 16:36
0.00 руб.
0 3 2
Здравствуйте!
Пишу лабораторную по теме "Драйвер клавиатуры" (полный код приведен ниже) и столкнулся с некоторыми трудностями:
1. Линковщик отказывается генерить COM-файл, выдаёт сообщение
"Fatal:Cannot generate COM-file:segment-relocatable items present" - в чём причина? вроде все данные описаны в сегменте кода, других сегментов нет...
2. обработчик прерывания (9h) на клавиатуру - требуется работа с портами, чего раньше никогда не делал. У Зубкова изложено только в теории, что помогает мало. Считал что-то там из порта и... что с этим делать? Да и неохота изобретать велосипед честно говоря... Может кто-нибудь поделится кусочком кода?

В общем вроде установил вектора на свои обработчики, а что дальше делать - ума не приложуАсм только изучаю, примеров катастрофически не хватает - как дальше реализовывать обработчики? Нужно ли в их начале вызывать старые обработчики и зачем эта мера вообще?
Немножко сумбурно получилось, но точнее не получается. Заранее спасибо.

Приложение:
.model tiny.286 ;разрешаем инструкции 286.codeorg 100h ;выделяем стековую памятьstart proc far push cs ;DS на сегмент кода pop ds push 0 pop es ;-----для клавиатуры----- push word ptr es:[9h*4] ;достаём смещение старого обработчика pop kbd_old_off ;сохраняем в переменной push word ptr es:[9h*4+2] ;достаём сегмент старого обработчика pop kbd_old_seg ;сохраняем в переменной ;-----для видеоадаптера----- push word ptr es:[10h*4] ;достаём смещение старого обработчика pop vga_old_off ;сохраняем в переменной push word ptr es:[10h*4+2] ;достаём сегмент старого обработчика pop vga_old_seg ;сохраняем в переменной pushf ;сохраняем в стек состояние флагов ;устанавливаем наш обработчик на клавиатуру cli ;запрещаем прерывания mov word ptr es:[9h*4],offset k_int ;в таблицу векторов - смещение нового обработчика mov word ptr es:[9h*4+2],seg k_int ;в таблицу векторов - сегмент нового обработчика ;устанавливаем наш обработчик на видео mov word ptr es:[10h*4],offset v_int ;в таблицу векторов - смещение нового обработчика mov word ptr es:[10h*4+2],seg v_int ;в таблицу векторов - сегмент нового обработчика popf ;восстановим исходное значение флага IF sti ; ;отработали здесь, после восстанавливаем вектора прерываний ; push 0 pop es pushf cli mov word ptr es:[9h*4],offset kbd_old_off ;в таблицу векторов - смещение нового обработчика mov word ptr es:[9h*4+2],seg kbd_old_seg ;в таблицу векторов - сегмент нового обработчика ;устанавливаем наш обработчик на видео mov word ptr es:[10h*4],offset vga_old_off ;в таблицу векторов - смещение нового обработчика mov word ptr es:[10h*4+2],seg vga_old_seg ;в таблицу векторов - сегмент нового обработчика popf sti retnstart endpk_int proc far ;обработчик клавиатуры pusha ;сохраняем все регистры общего назначения push es push ds push cs ;DS на сегмент кода pop ds in al,60h ;считали в AL скан-код клавиши push ax ;сохранили в стек in al,61h ;считали данные из порта 61h push ax ;закинули их в стек or al,80h ;установили бит 7 out 61h,al ;вывели назад в порт 61h pop ax ;достали данные из стека out 61h,al ;вывели назад в порт 61h pop ax ;восстановили скан-код клавиши в AX mov al,20h out 20h,al pop es pop ds popa iretk_int endpv_int proc far ;обработчик видео iretv_int endpkbd_old_off dw 0hkbd_old_seg dw 0hvga_old_off dw 0hvga_old_seg dw 0hend start

Обсуждение

Неизвестный
11.09.2006, 16:58
общий
это ответ
Здравствуйте, Дмитрий Валковой!

Вместо "seg k_int", "seg v_int" используйте cs - ведь все процедуры в одном сегменте (cs)...
В перывании из 60-го порта получил код нажатой(отжатой) клавиши, теперь осталось - по скан-коду определить код нажатой клавиши, создать в памяти буфер клавиатуры и добавить в него символ, соотвествующий этому коду (не забывая про shift, Caps, etc.)...
Неизвестный
12.09.2006, 10:21
общий
это ответ
Здравствуйте, Дмитрий Валковой!

Читать напрямую буфер клавиатуры (csan-code) Вы можете через порт 60h (scan-code 1 = Клавиша <ESC>; scan-code 2 = Клавиша F1 и т.д.), а управлять контроллером клавиатуры - через порт 64h.

Указатели на начало и конец буфера клавиатуры лежат по адресам 041Ah и 041Ch соответственно.

Если нужен "облагороженный" scan-code клавиши (с флагами Alt, Ctrl, Shift) - можно вызвать int 16h (ax = 01).

Статус флаги клавиатуры лежат здесь: 0040:0017 и 0040:0018 (это - слово) и имеют следующие значения:
bit| mask| value
0: 0001H alpha-shift (правая сторона) нажат
1: 0002H alpha-shift (левая сторона) нажат
2: 0004H Ctrl-shift (either side) нажат
3: 0008H Alt-shift (either side) нажат
4: 0010H ScrollLock состояние: включен
5: 0020H NumLock состояние: включен
6: 0040H CapsLock состояние: включен
7: 0080H Insert состояние: включен
8: 0100H Ctrl-shift (левая сторона) нажат
9: 0200H Alt-shift (левая сторона) нажат
10: 0400H Ctrl-shift (правая сторона) нажат
11: 0800H Alt-shift (правая сторона) нажат
12: 1000H ScrollLock нажат
13: 2000H NumLock нажат
14: 4000H CapsLock нажат
15: 8000H SysReq нажат

Получить в AX эти флаги можно через int 16h (ax = 12h).

Удачи!
Неизвестный
17.10.2006, 05:58
общий
Подскажите плиз заодно эффективный алгоритм перекодировки скан-кода в ASCII. не по таблице же это делать, это ж кошмар... перекодировка с учетом регистра нужна. в исполняемую часть вставилmov ah,1hint 21hи зациклил - пойдёт для вызова обработчика?
Форма ответа