[Форум] [Помощь] [Поиск] [Выйти] |
Добро пожаловать, User |
|
|
| ||
Недавно возникла потребность написать прогу под DOS, с продвинутой обработкой прерываний клавиатуры. Кто-нибудь занимался подобной хренотенью? Если да, может поделитесь опытом, как написать стабильный обработчик на С++, Паскале или на asm'е в конце концов. То, что написано на данный момент работает не совсем однозначно... Вот собсно, что имеется: {$F+} procedure kb_handler; interrupt; var kb_control,kb_data:byte; begin kb_data:=port[$60]; kb_control:=port[$61]; port[$61]:=kb_control or $80; delay(100); port[$61]:=kb_control; port[$20]:=$61; end; {$F-} |
| ||
а в чем проблемма? и зачем писать перехватчик, если значение от клавы и так доступно из порта 60 ? |
| ||
Проблема в том, что перехватчик то работает, то нет. Вернее выход из перехватчика осуществляется всегда, но клава частенько подвисает. Все зависит от того какие клавиши клацать и как клацать. Хотелось бы избавится от подобных капризов... Перехватчик я счел логичным написать потому, что прога должна управлять неким девайсом посредством нажатия клавиш и записи в соотв. порты, различать нажатие и отжатие клавиши. Я грешу на Delay(100), потому как не известно сколько это будет в миллисекундах на машине типа Duron 900. |
| ||
тогда попробуйте так: {$M 1024, 0, 0} var OldInt09h: Procedure; {$F+} procedure kb_handler; interrupt; begin inline($9c/$60); {pushf pusha} {ваш обработчик} inline($61/$9d); {popa popf} OldInt09h; end; {$F-} begin GetIntVec($9,@OldInt09h); SetIntVec($9,@kb_handler)); {.....} end. хотя на скока я помню, гораздо проще перехватывать int 8h(таймер) по такому же принципу, и обрабатывать собития от клавы. Вроде у меня тоже "глючило" если 9-е перехватывать :) |
| ||
может чо то не догоняю, но вроде handler: in al,60h ; прочитать скан-код клавиши cmp al, твоя гор. клавиша jne не_то ; перейти к нашему ; обработчику [...] ; наши действия здесь не_то: jmp стар_вектор ; вызов старого обработчика |
| ||
2 Goodmaker. Благодарю, но вариант с обращением к стандартному обработчику уже пробовался. Он конечно работает, но хотелось бы как-нибудь без него). Заменил фрагмент подтверждения ввода с операторами port[] следующей ассемблерной вставкой : asm in al,61h mov ah,al or al,80h out 61h,al mov al,ah out 61h,al mov al,61h out 20h,al end; Теперь работает. |
| ||
Проблема может быть в том, что нажатие (отпускание) клавиш генерирует от 1 до 6 байт скан-последовательностей. Во всех предложенных вариантах считывается только один. Более подробно о низкоуровневом программировании клавиатуры можно почитать в книге В. Кулакова "Программирование на аппаратном уровне". В общем советую сначала полностью считать то, что посылает контроллер клавиатуры. 0x61h порт можно не трогать - лучше до конца прочесть то что есть в 60-м :). Если проблема не исчезнет то будем смотреть дальше. |
| ||
Возможно, MOD прав... Однако, такой финт с 61м портом я встречал множество раз. Хоть в литературе и пишут, что дескать 61h - это порт спикера, к спикеру там относятся всего лишь два бита (0-й и 1-й). А старший бит как раз отвечает за сброс ввода с клавиатуры. ЗЫ: 3-й бит 61h когда-то отвечал за управление двигателем кассетного магнитофона =) Вот времена-то были.... |