<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=198375&amp;view=findpost&amp;p=2185466</guid>
        <pubDate>Mon, 02 Feb 2009 11:51:56 +0000</pubDate>
        <title>Драйвер клавиатуры</title>
        <link>https://forum.sources.ru/index.php?showtopic=198375&amp;view=findpost&amp;p=2185466</link>
        <description><![CDATA[X-Fly: Добрый день&#33;<br><br>Пытаюсь подключить вышеприведенный обработчик в программу на Паскале, но, то Паскаль ругается, то tasm...<br><br>Мне кажется, что это из-за модели памяти TINY в модулях на асме. И там нужно указать LARGE.<br>Но если изменить модель памяти, то tasm начинает ругаться:<br><br>(первые 4 ошибки - указывают на место описания таблицы перекодировки скан кодов)<br>**Error**  key.asm(44)  CS   unreachable   from  current   segment<br>**Error**  key.asm(52)  CS   unreachable   from  current   segment<br>**Error**  key.asm(60)  CS   unreachable   from  current   segment<br>**Error**  key.asm(68)  CS   unreachable   from  current   segment<br>**Error**  key.asm(139)  Relative   jump out   of   range   by   O002h bytes<br>**Error**  key.asm(146)  Relative   jump out   of   range   by   O002h bytes<br>(последние две - на джампы в процедуре key_Handler)<br><br>Подскажите, пожалуйста, что нужно поменять в коде обработчика, если изменять модель памяти на large?<br><br>Или может нужно в Паскале по-другому объявлять процедуры? (я пробовал указывать near; - не помогло... Покажите, пожалуйста, как нужно правильно объявить в Паскале все PUBLIC процедуры из этого обработчика...)]]></description>
        <author>X-Fly</author>
        <category>Assembler FAQ</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=198375&amp;view=findpost&amp;p=1658427</guid>
        <pubDate>Wed, 08 Aug 2007 12:02:12 +0000</pubDate>
        <title>Драйвер клавиатуры</title>
        <link>https://forum.sources.ru/index.php?showtopic=198375&amp;view=findpost&amp;p=1658427</link>
        <description><![CDATA[AndNot: <div class='tag-align-center'><span class='tag-size' data-value='13' style='font-size:13pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><strong class='tag-b'>Драйвер клавиатуры</strong></span></span></div><br>
При написании своих ОС, или при переходе в защищенный режим становится проблематичным использовать прерывания BIOS для работы с клавиатурой. Но создать свой драйвер несложно, хотя разработчики клавиатур постарались, чтобы жизнь программистам не казалась совсем уж медом :) <br>
Разумеется будет рассмотрен только второй режим работы клавиатуры - для PC/AT. В этом режиме клавиатуру можно разбить на следующие группы, по генерируемым скан-кодам:<ul class="tag-list"><li>Основная. Это та, что зародилась еще на 84-х клавишной XT. При нажатии клавиши в компьютер посылается однобайтный скан-код, который еще нужно перевести в ASCII. При отжатии посылается тот же код, но с установленным старшим битом.</li><li>Расширенная. При нажатии посылается 2 байта, первый - <em class='tag-i'>E0h</em>, затем скан-код, совпадающий с одной из клавиш основной клавиатуры. При отжатии так же посылается код <em class='tag-i'>E0h</em>, а затем скан-код, с установленным старшим битом.</li><li>Цифровая. Как и основная, посылает однобайтный скан-код, за исключением клавиш <em class='tag-i'>Enter</em> и <em class='tag-i'>&#39;/&#39;</em>, которые посылают расширенные коды.</li><li>Дополнительная. Генерирует последовательность из четырех байт, начинающихся с <em class='tag-i'>E0h</em>,<em class='tag-i'>2Ah</em>,<em class='tag-i'>E0h</em>, далее следует скан-код, совпадающий с одной из клавиш цифровой клавиатуры. При отжатии сначала посылается байт <em class='tag-i'>E0h</em>, затем скан-код, с установленным старшим битом, а затем последовательность из <em class='tag-i'>E0h</em> и <em class='tag-i'>AAh</em> (<em class='tag-i'>2Ah</em> с установленным старшим битом), т.е. в обратном порядке. В режиме автоповтора посылается последовательность из двух байт - <em class='tag-i'>E0h</em> и скан-кода клавиши. Заметим, что код <em class='tag-i'>2Ah</em> совпадает со скан-кодом клавиши <em class='tag-i'>Left Shift</em>.</li><li>Клавиша <em class='tag-i'>Pause/Break</em>. Стоит особняком, поскольку генерирует шесть байт, состоящих из кодов нажатия и отжатия (<em class='tag-i'>E1h</em>, <em class='tag-i'>1Dh</em>, <em class='tag-i'>45h</em>, <em class='tag-i'>E1h</em>, <em class='tag-i'>9Dh</em>, <em class='tag-i'>C5h</em>). Соответственно при отжатии ничего не генерируется. </li><li>Клавиши <em class='tag-i'>Win</em>, <em class='tag-i'>Applications</em>, <em class='tag-i'>Power</em>, <em class='tag-i'>Sleep</em>, <em class='tag-i'>Wake Up</em>. Генерируют расширенный код, соответственно и обрабатываются так же.</li></ul>Но не все так плохо. Если повнимательнее присмотреться к таблице скан-кодов, то нетрудно заметить что, отбросив комбинацию &lt;<em class='tag-i'>E0h</em>, <em class='tag-i'>2Ah</em>&gt;, мы сможем обрабатывать клавиши дополнительной клавиатуры как расширенные, что значительно облегчает задачу, поскольку остается учитывать только поступление байт <em class='tag-i'>E0h</em> и <em class='tag-i'>E1h</em>.<br>
Ниже представлен код драйвера, для примера, написанный под DOS. Чем-то напоминает обработчик BIOS, но не обрабатывает комбинации клавиш. Поддерживает смену раскладки клавиатуры (Eng/Rus). <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.model tiny, pascal</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;.8086</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;объявление экспортируемых функций драйвера &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">public key_Install &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; инициализация драйвера</div><div class="code_line">public key_Uninstall &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; выгрузка и восстановление старого</div><div class="code_line">public key_Wait8042In &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; ожидает готовности входного буфера i8042</div><div class="code_line">public key_Wait8042Out &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ожидает готовности выходного буфера i8042</div><div class="code_line">public key_Put &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; добавляет очередной символ и его скэн-код в очередь</div><div class="code_line">public key_Get &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; чтение символа из буфера клавиатуры</div><div class="code_line">public key_Status &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; чтение флагов состояния регистровых клавиш</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; константы &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">&nbsp;&nbsp;; биты состояния регистровых клавиш клавиатуры (Status[0])</div><div class="code_line">&nbsp;&nbsp;LSHIFT &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 01h &nbsp; &nbsp; ; левый Shift</div><div class="code_line">&nbsp;&nbsp;RSHIFT &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 02h &nbsp; &nbsp; ; правый Shift</div><div class="code_line">&nbsp;&nbsp;LCONTROL &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 04h &nbsp; &nbsp; ; левый Ctrl</div><div class="code_line">&nbsp;&nbsp;RCONTROL &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 08h &nbsp; &nbsp; ; правый Ctrl</div><div class="code_line">&nbsp;&nbsp;LALT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 10h &nbsp; &nbsp; ; левый Alt</div><div class="code_line">&nbsp;&nbsp;RALT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 20h &nbsp; &nbsp; ; правый Alt</div><div class="code_line">&nbsp;&nbsp;INSERT &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 40h &nbsp; &nbsp; ; Insert</div><div class="code_line">&nbsp;&nbsp;SYSREQ &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 80h &nbsp; &nbsp; ; PrtSc/SysRq</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;; биты состояния драйвера и управления светодиодами (Status[1])</div><div class="code_line">&nbsp;&nbsp;E0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 01h &nbsp; &nbsp; ; предыдущий скэн-код был E0h</div><div class="code_line">&nbsp;&nbsp;E1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 02h &nbsp; &nbsp; ; предыдущий скэн-код был E1h</div><div class="code_line">&nbsp;&nbsp;RUSLAT &nbsp; &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 04h &nbsp; &nbsp; ; Eng/Rus раскладка</div><div class="code_line">&nbsp;&nbsp;PAUSE &nbsp; &nbsp; &nbsp; &nbsp; equ &nbsp; &nbsp; 08h &nbsp; &nbsp; ; Pause/Break</div><div class="code_line">&nbsp;&nbsp;SCROLLLOCK &nbsp; &nbsp;equ &nbsp; &nbsp; 20h &nbsp; &nbsp; ; ScrollLock</div><div class="code_line">&nbsp;&nbsp;NUMLOCK &nbsp; &nbsp; &nbsp; equ &nbsp; &nbsp; 40h &nbsp; &nbsp; ; NumLock</div><div class="code_line">&nbsp;&nbsp;CAPSLOCK &nbsp; &nbsp; &nbsp;equ &nbsp; &nbsp; 80h &nbsp; &nbsp; ; CapsLock</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;данные &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">.data</div><div class="code_line">&nbsp;&nbsp;; таблицы перекодировки, местами не менять!</div><div class="code_line">&nbsp;&nbsp;Symb:</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 ,1bh,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;0&#39;,&#39;-&#39;,&#39;=&#39;, 8 , 9</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;q&#39;,&#39;w&#39;,&#39;e&#39;,&#39;r&#39;,&#39;t&#39;,&#39;y&#39;,&#39;u&#39;,&#39;i&#39;,&#39;o&#39;,&#39;p&#39;,&#39;[&#39;,&#39;]&#39;, 13, -1,&#39;a&#39;,&#39;s&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;d&#39;,&#39;f&#39;,&#39;g&#39;,&#39;h&#39;,&#39;j&#39;,&#39;k&#39;,&#39;l&#39;,&#39;;&#39;,&quot;&#39;&quot;,&#39;`&#39;, -1,&#39;\&#39;,&#39;z&#39;,&#39;x&#39;,&#39;c&#39;,&#39;v&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;b&#39;,&#39;n&#39;,&#39;m&#39;,&#39;,&#39;,&#39;.&#39;,&#39;/&#39;, -1,&#39;*&#39;, -1,&#39; &#39;, -1, 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 , 0 , 0 , 0 , 0 , -1, -1, 0 , 0 , 0 ,&#39;-&#39;, 0 , 0 , 0 ,&#39;+&#39;, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 , 0 , -1, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db 32 dup (0)</div><div class="code_line">&nbsp;&nbsp;SymbRus:</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 ,1bh,&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;0&#39;,&#39;-&#39;,&#39;=&#39;, 8 , 9</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;й&#39;,&#39;ц&#39;,&#39;у&#39;,&#39;к&#39;,&#39;е&#39;,&#39;н&#39;,&#39;г&#39;,&#39;ш&#39;,&#39;щ&#39;,&#39;з&#39;,&#39;х&#39;,&#39;ъ&#39;, 13, -1,&#39;ф&#39;,&#39;ы&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;в&#39;,&#39;а&#39;,&#39;п&#39;,&#39;р&#39;,&#39;о&#39;,&#39;л&#39;,&#39;д&#39;,&#39;ж&#39;,&#39;э&#39;,&#39;)&#39;, -1,&#39;\&#39;,&#39;я&#39;,&#39;ч&#39;,&#39;с&#39;,&#39;м&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;и&#39;,&#39;т&#39;,&#39;ь&#39;,&#39;б&#39;,&#39;ю&#39;,&#39;ё&#39;, -1,&#39;*&#39;, -1,&#39; &#39;, -1, 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 , 0 , 0 , 0 , 0 , -1, -1, 0 , 0 , 0 ,&#39;-&#39;, 0 , 0 , 0 ,&#39;+&#39;, 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 , 0 , -1, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db 32 dup (0)</div><div class="code_line">&nbsp;&nbsp;SymbShift:</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 ,1bh,&#39;!&#39;,&#39;@&#39;,&#39;#&#39;,&#39;$&#39;,&#39;%&#39;,&#39;^&#39;,&#39;&amp;&#39;,&#39;*&#39;,&#39;(&#39;,&#39;)&#39;,&#39;_&#39;,&#39;+&#39;, 8 , 9</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;Q&#39;,&#39;W&#39;,&#39;E&#39;,&#39;R&#39;,&#39;T&#39;,&#39;Y&#39;,&#39;U&#39;,&#39;I&#39;,&#39;O&#39;,&#39;P&#39;,&#39;{&#39;,&#39;}&#39;, 13, -1,&#39;A&#39;,&#39;S&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;D&#39;,&#39;F&#39;,&#39;G&#39;,&#39;H&#39;,&#39;J&#39;,&#39;K&#39;,&#39;L&#39;,&#39;:&#39;,&#39;&quot;&#39;,&#39;~&#39;, -1,&#39;|&#39;,&#39;Z&#39;,&#39;X&#39;,&#39;C&#39;,&#39;V&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;B&#39;,&#39;N&#39;,&#39;M&#39;,&#39;&#60;&#39;,&#39;&#62;&#39;,&#39;?&#39;, -1,&#39;*&#39;, -1,&#39; &#39;, -1, 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 , 0 , 0 , 0 , 0 , -1, -1,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;-&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;+&#39;,&#39;1&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;2&#39;,&#39;3&#39;,&#39;0&#39;,&#39;.&#39;, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db 32 dup (0)</div><div class="code_line">&nbsp;&nbsp;SymbRusShift:</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 ,1bh,&#39;!&#39;,&#39;&quot;&#39;,&#39;/&#39;,&#39;$&#39;,&#39;:&#39;,&#39;,&#39;,&#39;.&#39;,&#39;;&#39;,&#39;?&#39;,&#39;%&#39;,&#39;_&#39;,&#39;+&#39;, 8 , 9</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;Й&#39;,&#39;Ц&#39;,&#39;У&#39;,&#39;К&#39;,&#39;Е&#39;,&#39;Н&#39;,&#39;Г&#39;,&#39;Ш&#39;,&#39;Щ&#39;,&#39;З&#39;,&#39;Х&#39;,&#39;Ъ&#39;, 13, -1,&#39;Ф&#39;,&#39;Ы&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;В&#39;,&#39;А&#39;,&#39;П&#39;,&#39;Р&#39;,&#39;О&#39;,&#39;Л&#39;,&#39;Д&#39;,&#39;Ж&#39;,&#39;Э&#39;,&#39;(&#39;, -1,&#39;|&#39;,&#39;Я&#39;,&#39;Ч&#39;,&#39;С&#39;,&#39;М&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;И&#39;,&#39;Т&#39;,&#39;Ь&#39;,&#39;Б&#39;,&#39;Ю&#39;,&#39;Ё&#39;, -1,&#39;*&#39;, -1,&#39; &#39;, -1, 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &nbsp;0 , 0 , 0 , 0 , 0 , -1, -1,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;-&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;+&#39;,&#39;1&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp;db &#39;2&#39;,&#39;3&#39;,&#39;0&#39;,&#39;.&#39;, 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;db 32 dup (0)</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;; код переключения раскладки клавиатуры (Rus/Eng)</div><div class="code_line">&nbsp;&nbsp;LangSwitch &nbsp; &nbsp;db 1Dh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; клавиша &nbsp; &nbsp; &nbsp; - Ctrl</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db RCONTROL &nbsp; &nbsp; ; флаги &nbsp; &nbsp; &nbsp; &nbsp; - правый</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; неинициализированные данные &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">.data?</div><div class="code_line">&nbsp;&nbsp;; состояние клавиатуры</div><div class="code_line">&nbsp;&nbsp;Status &nbsp; &nbsp; &nbsp; &nbsp;db ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; состояние регистровых клавиш</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; состояние драйвера и светодиодов</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;; буфер драйвера клавиатуры</div><div class="code_line">&nbsp;&nbsp;buf_tail &nbsp; &nbsp; &nbsp;dw ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; указатель на последний введенный символ</div><div class="code_line">&nbsp;&nbsp;buf_head &nbsp; &nbsp; &nbsp;dw ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; указатель на первый введенный символ</div><div class="code_line">&nbsp;&nbsp;buf_code &nbsp; &nbsp; &nbsp;dw 32 dup(?) &nbsp; &nbsp;; сам буфер</div><div class="code_line">&nbsp;&nbsp;buf_end &nbsp; &nbsp; &nbsp; equ ($-buf_code)/2</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;; адрес старого обработчика прерываний клавиатуры</div><div class="code_line">&nbsp;&nbsp;oldOfsIRQ1 &nbsp; &nbsp;dw ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; его смещение</div><div class="code_line">&nbsp;&nbsp;oldSegIRQ1 &nbsp; &nbsp;dw ? &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; и сегмент</div><div class="code_line">&nbsp;&nbsp;; старое состояние светодиодов</div><div class="code_line">&nbsp;&nbsp;oldLed &nbsp; &nbsp; &nbsp; &nbsp;db ?</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;код &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="code_line">;+---------------------------------------------------------------------------+</div><div class="code_line">.code</div><div class="code_line">&nbsp;</div><div class="code_line">; обработчик IRQ 1 - прерывания, генерируемого контроллером клавиатуры</div><div class="code_line">key_Handler proc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сохраняем используемые нами регистры и настраиваем регистр DS на сегмент данных</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;ds es ax bx cx dx si di bp</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;push &nbsp; &nbsp;cs</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; ds &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; ds - наш сегмент данных (для модели TINY)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; получаем пришедший байт</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dx, 60h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp; &nbsp;al, dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ah, al</div><div class="code_line">&nbsp;&nbsp; &nbsp;; для IBM XT и более ранних моделей необходимо уведомить контроллер клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp;; о приеме данных, через порт 61h. если не предполагается поддержка таких</div><div class="code_line">&nbsp;&nbsp; &nbsp;; древних компьютеров, то можно смело убрать следующие 6 строк кода.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp; &nbsp;al, dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;al, 80h &nbsp; &nbsp; &nbsp; &nbsp; ; устанавливаем режим &quot;только чтение&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; dx, al &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; отсылаем контроллеру</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; al, 7fh &nbsp; &nbsp; &nbsp; &nbsp; ; отменяем режим &quot;только чтение&quot;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; dx, al &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; теперь контроллер готов к посылке следующего байта</div><div class="code_line">&nbsp;&nbsp; &nbsp;; разрешаем прерывания, поскольку задерживать их крайне нежелательно</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, 20h &nbsp; &nbsp; &nbsp; &nbsp; ; al - команда EOI (End Of Interrupt)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; 20h, al &nbsp; &nbsp; &nbsp; &nbsp; ; отсылает ее контроллеру прерываний</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; теперь вызываем функцию 4fh, прерывания 15h.</div><div class="code_line">&nbsp;&nbsp; &nbsp;; эта функция доступна на всех ЭВМ, кроме PC, PCjr, XT</div><div class="code_line">&nbsp;&nbsp; &nbsp;; от 11/08/82 и AT от 01/10/84.</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, 4fh</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xchg &nbsp; &nbsp;al, ah &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; al - скэн-код / ah - номер функции</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;int &nbsp; &nbsp; 15h</div><div class="code_line">&nbsp;&nbsp; &nbsp;; на выходе:</div><div class="code_line">&nbsp;&nbsp; &nbsp;; &nbsp; флаг CF = 0 - игнорировать скан-код</div><div class="code_line">&nbsp;&nbsp; &nbsp;; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - занести скан-код в буфер клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp;; &nbsp; &nbsp; &nbsp; &nbsp;AL = скан-код (старый или подмененный)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jnc &nbsp; &nbsp; @@iret</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; начинаем обработку пришедшего символа</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; bx, bx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; номер таблицы перекодировки</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ah, al</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], E1 &nbsp; ; если установлен бит E1,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jnz &nbsp; &nbsp; @@pause &nbsp; &nbsp; &nbsp; &nbsp; ; &#60;- то идет прием кодов Pause/Break</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; если у скэн-кода установлен старший бит, то пришел код отжатой клавиши</div><div class="code_line">&nbsp;&nbsp; &nbsp;; или начало последовательности кодов расширенной/дополнительной клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;al, al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jns &nbsp; &nbsp; @@isextcode</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 0e0h &nbsp; &nbsp; &nbsp; &nbsp;; E0h - первый байт скэн-кода расширенной/доп. клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@ispause</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;Status[1], E0 &nbsp; ; устанавливаем признак приема расширенного скэн-кода</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@iret &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; и будем дожидаться собственно байта скэн-кода клавиши</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@ispause:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 0e1h &nbsp; &nbsp; &nbsp; &nbsp;; E1h - начальный байт Pause/Break</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@keyup</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;Status[1], E1 &nbsp; ; устанавливаем признак приема скэн-кода от Pause/Break</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@iret &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; и ждем остальную последовательнось байт</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@keyup:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_Release &nbsp; &nbsp; ; из отжатых нас интересуют Ctrl, Alt и Shift</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@exit</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isextcode:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], E0 &nbsp; ; если установлен бит E0, то идет прием очередного</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jnz &nbsp; &nbsp; @@extcode &nbsp; &nbsp; &nbsp; ; байта скэн-кода клавиши расширенной/доп. клавиатуры</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; получен однобайтовый код основной клавиатуры,</div><div class="code_line">&nbsp;&nbsp; &nbsp;; пытаемся преобразовать его в ascii символ, с учетом состояния регистровых клавиш</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], RUSLAT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;@@isshift</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; bx</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isshift:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[0], (LSHIFT or RSHIFT)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;@@isnumlock</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; bx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; bx</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isnumlock: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; если включен NumLock, то обрабатываем немного по другому</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], NUMLOCK</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;@@xlat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 47h &nbsp; &nbsp; &nbsp; &nbsp; ; на цифровой клавиатуре?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jb &nbsp; &nbsp; &nbsp;@@xlat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 53h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ja &nbsp; &nbsp; &nbsp;@@xlat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;neg &nbsp; &nbsp; bx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; меняем 0|1 таблицу на 2|3 таблицу</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; bx, 3</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@xlat:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shl &nbsp; &nbsp; bx, 7 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; bx = bx * 128 = bx * sizeof(таблица перекодировки)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; bx, offset Symb</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xlat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; al = bx[al] = SymbTable[al]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, -1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; это регистровая клавиша?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@keydown &nbsp; &nbsp; &nbsp; ; &#60;- да, нужно изменить ее статус</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], CAPSLOCK</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;@@savecode</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_ChangeReg &nbsp; ; при включенном SapsLock меняем регистр клавиш</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@savecode:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_Put &nbsp; &nbsp; &nbsp; &nbsp; ; ложим получившийся код в буфер</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@exit:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; Status[1], not E0</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@iret:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;pop &nbsp; &nbsp; bp di si dx cx bx ax es ds</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;iret</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; обработка нажатия Pause/Break (последовательность кодов - E1h,1Dh,45h,E1h,9Dh,C5h)</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@pause:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 0c5h &nbsp; &nbsp; &nbsp; &nbsp;; это конец последовательности?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@exit</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; Status[1], not E1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; Status[1], PAUSE; меняем состояние на противоположное</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@exit</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; пришел код расширенной/доп. клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@extcode:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 2ah</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@exit &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; &#60;- пропускаем код E0h,2Ah</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; выясняем, не регистровая ли клавиша нажата?</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@keydown:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, ah &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; команды с регистром AL короче на один байт :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, LALT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 38h &nbsp; &nbsp; &nbsp; &nbsp; ; нажат Alt?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@isrightdn</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ja &nbsp; &nbsp; &nbsp;@@isled &nbsp; &nbsp; &nbsp; &nbsp; ; коды 3Ah и выше принадлежат клавишам управления светодиодами</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, LSHIFT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 2ah &nbsp; &nbsp; &nbsp; &nbsp; ; нажат левый Shift?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@savedn</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, RSHIFT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 36h &nbsp; &nbsp; &nbsp; &nbsp; ; нажат правый Shift?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@savedn</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, LCONTROL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 1dh &nbsp; &nbsp; &nbsp; &nbsp; ; нажат Ctrl?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@isrightdn</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 37h &nbsp; &nbsp; &nbsp; &nbsp; ; нажат Print Screen?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@unccode</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; Status[0], SYSREQ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@exit</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isrightdn:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], E0 &nbsp; ; если предыдущий код был E0h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;@@savedn &nbsp; &nbsp; &nbsp; &nbsp;; то это правый Ctrl/Alt</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;add &nbsp; &nbsp; dh, dh &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; сдвигаем бит влево (делаем клавишу правой)</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@savedn:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;Status[0], dh &nbsp; ; устанавливаем бит нажатой регистровой клавиши</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@exit &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; и уходим</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; проверяем на нажатие клавиши управления светодиодами и Insert</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isled:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, SCROLLLOCK</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 46h &nbsp; &nbsp; &nbsp; &nbsp; ; нажат ScrollLock?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@led</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, NUMLOCK</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 45h &nbsp; &nbsp; &nbsp; &nbsp; ; нажат NumLock?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@led</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, CAPSLOCK</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 3ah &nbsp; &nbsp; &nbsp; &nbsp; ; нажат CapsLock?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@led</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 52h &nbsp; &nbsp; &nbsp; &nbsp; ; а может Insert?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@unccode &nbsp; &nbsp; &nbsp; ; &#60;- это не регистровая клавиша, просто заносим в буфер</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; Status[0], INSERT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@unccode &nbsp; &nbsp; &nbsp; ; &#60;- Insert тоже кладем в буфер</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@led:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; Status[1], dh &nbsp; ; переключаем бит клавиши в противоположное состояние</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_SwitchLed</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@exit</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;; сюда попадают все остальные коды расширенной/доп. клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@unccode:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; al, al &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; обнуляем код ascii-символа</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jmp &nbsp; &nbsp; @@savecode &nbsp; &nbsp; &nbsp;; и сохраняем скэн-код в буфер</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;; пришел код отжатия клавиши (в регистре AL), уточняем какой</div><div class="code_line">&nbsp;&nbsp;key_Release:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], E0</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jnz &nbsp; &nbsp; @@isrshift &nbsp; &nbsp; &nbsp;; &#60;- пропускаем код E0h,AAh(2ah+80h)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, not LSHIFT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 2ah+80h &nbsp; &nbsp; ; отжат левый Shift?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@islang</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isrshift:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, not RSHIFT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 36h+80h &nbsp; &nbsp; ; отжат правый Shift?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@islang</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, not LCONTROL</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 1dh+80h &nbsp; &nbsp; ; отжат Ctrl?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@isrightup</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dh, not LALT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, 38h+80h &nbsp; &nbsp; ; отжат Alt?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@doneup</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isrightup:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;Status[1], E0 &nbsp; ; если предыдущий код был E0h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jz &nbsp; &nbsp; &nbsp;@@islang &nbsp; &nbsp; &nbsp; &nbsp;; то это правый Ctrl/Alt</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;rol &nbsp; &nbsp; dh, 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; сдвигаем бит влево (делаем клавишу правой)</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@islang:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; проверяем на наличие переключения раскладки клавиатуры (Rus/Eng)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; al, 7fh &nbsp; &nbsp; &nbsp; &nbsp; ; сбрасываем бит отжатия клавиши</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, LangSwitch[0]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@saveup</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, LangSwitch[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; al, Status[0]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, LangSwitch[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jne &nbsp; &nbsp; @@saveup</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; Status[1], RUSLAT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_SetBorder &nbsp; ; отмечаем текущий режим цветом бордюра</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@saveup:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; Status[0], dh &nbsp; ; убираем бит нажатия клавиши</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@doneup:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;retn</div><div class="code_line">key_Handler endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; изменяет регистр букв (строчные/прописные) в регистре AL</div><div class="code_line">key_ChangeReg proc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;ё&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ja &nbsp; &nbsp; &nbsp;@@done</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;Ё&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jb &nbsp; &nbsp; &nbsp;@@next</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; al, 1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@next:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;р&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jae &nbsp; &nbsp; @@50</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;п&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ja &nbsp; &nbsp; &nbsp;@@done</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;а&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jae &nbsp; &nbsp; @@20</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;Р&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jae &nbsp; &nbsp; @@50</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;А&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jae &nbsp; &nbsp; @@20</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;z&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ja &nbsp; &nbsp; &nbsp;@@done</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al, &#39;a&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jae &nbsp; &nbsp; @@20</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al,&#39;Z&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ja &nbsp; &nbsp; &nbsp;@@done</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; al,&#39;A&#39;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jae &nbsp; &nbsp; @@20</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@done:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@50:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; al, 50h</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@20:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; al, 20h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_ChangeReg endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; зажигает/гасит светодиоды</div><div class="code_line">key_SwitchLed proc</div><div class="code_line">&nbsp;&nbsp;uses ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_Wait8042In &nbsp;; ждем готовности входного буфера клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, 0edh &nbsp; &nbsp; &nbsp; &nbsp;; команда установки светодиодов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; 60h, al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_Wait8042In</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, Status[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shr &nbsp; &nbsp; al, 8-3 &nbsp; &nbsp; &nbsp; &nbsp; ; выделяем биты, отвечающие за состояние светодиодов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; 60h, al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_SwitchLed endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; устанавливает цвет бордюра экрана, в зависимости от текущей раскладки (Rus/Eng)</div><div class="code_line">key_SetBorder proc</div><div class="code_line">&nbsp;&nbsp;uses dx, ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dx, 3dah &nbsp; &nbsp; &nbsp; &nbsp;; очищаем индекс регистра 3c0h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp; &nbsp;al, dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dx, 3c0h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, 31h</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; dx, al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, Status[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;and &nbsp; &nbsp; al, RUSLAT</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; dx, al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_SetBorder endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; ожидает готовности входного буфера i8042</div><div class="code_line">; на выходе:</div><div class="code_line">; &nbsp; &nbsp; флаг ZF: &nbsp;0 - ошибка тайм-аута</div><div class="code_line">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 - все ок, буфер свободен</div><div class="code_line">key_Wait8042In proc</div><div class="code_line">&nbsp;&nbsp;uses cx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;cx, -1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; защита от зацикливания</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@waitin:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp; &nbsp;al, 64h &nbsp; &nbsp; &nbsp; &nbsp; ; читаем регистр состояния клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;al, 10b &nbsp; &nbsp; &nbsp; &nbsp; ; буфер 8042 свободен?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;loopnz &nbsp;@@waitin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Wait8042In endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; ожидает готовности выходного буфера i8042</div><div class="code_line">; на выходе:</div><div class="code_line">; &nbsp; &nbsp; флаг ZF: &nbsp;1 - ошибка тайм-аута</div><div class="code_line">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 - все ок, буфер свободен</div><div class="code_line">key_Wait8042Out proc</div><div class="code_line">&nbsp;&nbsp;uses cx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;cx, -1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; защита от зацикливания</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@waitout:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp; &nbsp;al, 64h &nbsp; &nbsp; &nbsp; &nbsp; ; читаем регистр состояния клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;test &nbsp; &nbsp;al, 1b &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; буфер 8042 свободен?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;loopz &nbsp; @@waitout</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Wait8042Out endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; добавляет очередной символ и его скэн-код в очередь буфера драйвера клавиатуры</div><div class="code_line">; на входе:</div><div class="code_line">; &nbsp; &nbsp; &nbsp; al &nbsp; &nbsp; &nbsp;- ASCII символ или 0</div><div class="code_line">; &nbsp; &nbsp; &nbsp; ah &nbsp; &nbsp; &nbsp;- скэн-код</div><div class="code_line">key_Put proc</div><div class="code_line">&nbsp;&nbsp;uses bx, dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cli &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; нас нельзя прерывать :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; bx, [buf_tail]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dx, bx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; dx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; dx - следующая позиция в буфере</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dx, buf_end &nbsp; &nbsp; ; нет ли выхода за пределы буфера?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jb &nbsp; &nbsp; &nbsp;@@isover</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; dx, dx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; вышли, переходим в его начало</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@isover:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shl &nbsp; &nbsp; bx, 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; bx = bx*2</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dx, [buf_head] &nbsp;; есть ли место в буфере?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@overflow</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; buf_code[bx], ax; пересылаем в буфер</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [buf_tail], dx &nbsp;; сохраняем новую позицию</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@overflow: ; произошло переполнение буфера, символ будет потерян</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Put endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; чтение символа и его скэн-кода из буфера клавиатуры</div><div class="code_line">; на выходе:</div><div class="code_line">; &nbsp; &nbsp; &nbsp; флаг ZF - 0, если символ считан</div><div class="code_line">; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; - 1, если буфер пуст</div><div class="code_line">; &nbsp; &nbsp; &nbsp; al &nbsp; &nbsp; &nbsp;- ASCII символ или 0 (при ZF=0)</div><div class="code_line">; &nbsp; &nbsp; &nbsp; ah &nbsp; &nbsp; &nbsp;- скэн-код (при ZF=0)</div><div class="code_line">key_Get proc</div><div class="code_line">&nbsp;&nbsp;uses bx, dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cli &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; нас нельзя прерывать :)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; bx, [buf_head]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; dx, bx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; bx, [buf_tail] &nbsp;; буфер пуст?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;je &nbsp; &nbsp; &nbsp;@@empty &nbsp; &nbsp; &nbsp; &nbsp; ; &#60;-- да</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; извлекаем очередной символ и его скэн-код</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shl &nbsp; &nbsp; bx, 1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; bx = bx*2</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;inc &nbsp; &nbsp; dx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; dx - следующая позиция в буфере</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ax, buf_code[bx]; получаем очередной символ и скэн-код</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cmp &nbsp; &nbsp; dx, buf_end &nbsp; &nbsp; ; нет ли выхода за пределы буфера?</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;jb &nbsp; &nbsp; &nbsp;@@save</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; dx, dx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; был, переходим в начало буфера</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@save:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [buf_head], dx</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;or &nbsp; &nbsp; &nbsp;ax, ax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; сбрасываем флаг ZF</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">&nbsp;&nbsp; &nbsp;@@empty: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; буфер пуст, возвращаем взведенный флаг ZF</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Get endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; чтение флагов состояния регистровых клавиш</div><div class="code_line">; на выходе:</div><div class="code_line">; &nbsp; &nbsp; &nbsp; al &nbsp; &nbsp; &nbsp;- флаг регистровых клавиш</div><div class="code_line">; &nbsp; &nbsp; &nbsp; ah &nbsp; &nbsp; &nbsp;- флаг состояния драйвера и светодиодов</div><div class="code_line">key_Status proc</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, Status[0]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ah, Status[1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Status endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; инициализирует внутренние переменные и устанавливает свой обработчик прерываний клавиатуры</div><div class="code_line">key_Install proc</div><div class="code_line">&nbsp;&nbsp;uses ax, es</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; ax, ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; es, ax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; es - сегмент данных BIOS</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; инициализируем переменные</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; Status[0], al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; Status[1], al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [buf_head], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [buf_tail], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сохраняем статус светодиодов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, es: [417h]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [oldLed], al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; гасим светодиоды</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_SwitchLed</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; сохраняем прежний вектор обработчика прерывания клавиатуры</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cli</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ax, es: [9*4] &nbsp; ; IRQ 1 аппаратно накладывается на 9-й вектор</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [oldOfsIRQ1], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ax, es: [9*4+2]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; [oldSegIRQ1], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; устанавливаем свой</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ax, offset key_Handler</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; es: [9*4], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; es: [9*4+2], cs</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Install endp</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">; восстанавливает прежний обработчик прерываний клавиатуры</div><div class="code_line">key_Uninstall proc</div><div class="code_line">&nbsp;&nbsp;uses ax, es</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; восстанавливаем IRQ</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;cli</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;xor &nbsp; &nbsp; ax, ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; es, ax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; es - сегмент данных BIOS</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ax, [oldOfsIRQ1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; es: [9*4], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; ax, [oldSegIRQ1]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; es: [9*4+2], ax</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;sti</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;; восстанавливаем состояние светодиодов</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; al, [oldLed]</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;shl &nbsp; &nbsp; al, 1</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;mov &nbsp; &nbsp; Status[1], al</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;call &nbsp; &nbsp;key_SwitchLed</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;ret</div><div class="code_line">key_Uninstall endp</div><div class="code_line">&nbsp;</div><div class="code_line">end</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
Компилируется так:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">tasm /m3 key.asm</div></ol></div></div></div></div><br>
В аттаче таблица скан-кодов, а так же небольшой пример - установка временных характеристик клавиатуры.<br>
Особая благодарность <strong class='tag-b'>7in X</strong>, за предоставленные сорсы, которые навели на пару интересных идей, по реализации драйвера.]]></description>
        <author>AndNot</author>
        <category>Assembler FAQ</category>
      </item>
	
      </channel>
      </rss>
	