нажата ли в данный момент клавиша-переключатель. В [3.2.3] показано, как использовать клавишу ScrollLock, в качестве переключателя с любой другой клавишей клавиатуры. Другие комбинации с клавишами-перек- лючателями можно сделать допустимыми только полностью переписав прерывание клавиатуры, которое заменило бы прерывание BIOS [3.1.9]. Имеется проблема, связанная с некоторыми комбинациями с клави- шей Ctrl, такими как Ctrl + H, I, M и [, поскольку они генерируют коды ASCII, идентичные тем, которые генерируют клавиши <BackSpa- ce>, <Tab>, <Enter> и <Escape>. В [3.1.8] показано как программа на ассемблере может может, проверив скан-коды, определить была ли нажата управляющая клавиша или комбинация буквы с Ctrl (скан-код находится в AH, когда мы получаем код нажатой клавиши через пре- рывание 16H). К сожалению, программы на Бейсике лишены такой возможности. В таком случае программа может попытаться различить эти две возможности, анализируя состояние регистра статуса. Если бит 2 байта статуса по адресу 0040:0017 установлен, то клавиша Ctrl - нажата. Этот метод работает только в тот момент, когда происходит нажатие клавиши, но не тогда, когда Вы берете символ из буфера клавиатуры через некоторое время. Клавиатура PCjr имеет только 63 клавиши, по сравнению с 83 для IBM PC или XT и 84 для AT. Некоторые комбинации клавиш-переключа- телей служат для имитации некоторых недостающих клавиш (комбина- ции с использованием функциональных клавиш приведены в [3.2.5]): Комбинация клавиш PCjr PC/XT/AT эквиваленты Alt + Fn + 0-9 0-9 (скан-коды дополнительной циф- ровой клавиатуры Alt + / \ Alt + ' ` Alt + [ | Alt + ] ~ Alt + . * (скан-код, как от клавиши PrtSc Shift + Del . (скан-код, как от доп. кл-ры) Клавиатура PCjr допускает также следующие уникальные комбина- ции с участием клавиш-переключателей: Fn + Shift + Esc переключает цифровые клавиши в функциональные Ctrl + Alt + CapsLock переключает звуковое подтверждение нажатия клавиши Ctrl + Alt + Ins запускает диагностику Ctrl + Alt + CursorLeft сдвигает экран влево Ctrl + Alt + CursorRight сдвигает экран вправо 3.2.3 Использование клавиш-переключателей: NumLock, CapsLock, Ins и ScrollLock. За исключением клавиши Ins, все остальные клавиши-переключате- ли не производят кода, который помещался бы в буфер клавиатуры. Вместо этого, они изменяют состояние двух байтов статуса, которые расположены в области данных BIOS по адресам 0040:0017 и 0040:0018. Прерывание клавиатуры проверяет установку этих байтов перед тем как присвоить код введенному символу. Ваши программы имеют доступ к регистрам статуса и могут изменить установку любой из клавиш-переключателей как объяснено в [3.1.7]. Другие биты регистра статуса показывают нажата ли данная кла- виша-переключатель в текущий момент. Это свойство позволяет прог- рамме использовать клавиши-переключатели в качестве клавиш сдви- га. Возможны потенциальные применения этого, пока не создано новых кодов клавиш. Например, <ScrollLock> может быть итспользо- ван для того, чтобы добавить добавочный набор комбинаций сдвиг + функциональная клавиатура. Программа, которая будет получать код обычной функциональной клавиши, проверять нажата ли клавиша <ScrollLock> и соответственно интерпретировать нажатие клавиши. Отметим, что любая из клавиш <Shift> обращает текущую установку клавиши <NumLock>. Клавиша <Ins> помещает в буфер клавиатуры код 0;82, который Ваша программа может прочитать в любой момент. Однако установка для <Ins> в байтах регистра статуса меняется немедленно. Даже если в буфере нет места для кода <Ins>, то в регистре статуса при нажатии клавиши вносятся изменения. Как <Ins>, так и <Scroll- Lock>, не влияют на другие клавиши клавиатуры (в отличие от <Num- Lock> и <CapsLock>). Вы можете приписать им любую роль, какую захотите. Техническое руководство IBM утверждает, что клавиша <ScrollLock> должна использоваться для переключения между состоя- ниями, когда нажатие клавиши перемещения курсора приводит к сдвижке экрана, а не к передвижению курсора. Конечно, Вы можете создать все требуемые Вашей программе кла- виши-переключатели просто назначив клавиши для этой цели. Хотя для этой цели Вы не имеете готовых регистров статуса, но Вы може- те создать переменную, значение которой -1 соответствует включен- ному состоянию Вашего переключателя, а значение 0 - выключенному. Например, используем клавишу F10 для включения и выключения пере- менной Clock: 100 '''переключение статуса переменной 110 CLOCK = -1 'начинаем с включенным состоянием 120 IF X<=100 THEN NOT CLOCK 'переключаем переменную 3.2.4 Использование цифровой дополнительной клавиатуры и клавиш перемещения курсора. Для IBM PC и XT дополнительная цифровая клавиатура включает цифровые клавиши, клавиши <Ins> и <Del>, а также клавиши + и -. На AT добавляется клавиша "System Request" (Sys Rec), в то время как PCjr имеет только 4 клавиши перемещения курсора (остальные могут быть эмулированы специальными комбинациями с клавишами <Shift> и <Fn>, описанными в [3.2.2] и [3.2.5]). Клавиша <Num- Lock> переключает между цифрами и клавишами управления курсором. Клавиши <Ins> и <Del> работают только если режим <NumLock> вклю- чен, т.е. дополнительная клавиатура выдает цифры. Клавиши + и - выдают одни и те же коды независимо от установки режима <Num- Lock>. Цифровые клавиши дополнительной клавиатуры выдают в точности те же однобайтные коды, которые выдают цифровые клавиши верхнего ряда основной клавиатуры - т.е. коды ASCII от 48 до 57 для цифр от 0 до 9. Это верно и для клавиш + и -. Программисты на ассемб- лере могут определить какая из двух клавиш нажата по скан-коду клавиши, который находится в AH при возврате как из прерывания 16H, так и из процедур ввода одной клавиши прерывания 21H. Отме- тим, что любая из клавиш <Shift> переводит клавиши дополнительной клавиатуры в режим противоположный тому, который установлен кла- вишей <NumLock>. Установка клавиши <CapsLock> не имеет значения. Клавиша "5" в центре активна только как цифровая клавиша и в режиме перемещения курсора ввобще не выдает кода. Кроме четырех общепринятых стрелок клавиши управления курсором включают также <Home>, <End>, <PgUp> и <PgDn>, которые часто используются для перемещения курсора сразу на целую строку или страницу. Все они генерируют двухбайтные расширенные коды. Эти клавиши не обеспечивают прямого контроля над курсором. Они просто выдают коды, как и все другие клавиши, и это уже задача програм- миста преобразовать эти коды в перемещения курсора на экране. Допустимы некоторые комбинации клавиш дополнительной клавиату- ры с клавишей Ctrl. <NumLock> должен соответствовать режиму уп- равления курсором, чтобы эти комбинации работали. В [3.1.7] пока- зано как Ваша программа может автоматически устанавливать режим NumLock. Вот перечень кодов клавиш дополнительной клавиатуры: Коды ASCII: 43 + 45 - 46 . 48-57 0-9 Расширенные коды: 72,75,77,80 CursorUp,Left,Right&Down 71,73,79,81 Home,PgUp,End,PgDn 82,83 Ins,Del 115,116 Ctlr-cursor left, -cursor right 117,118,119,132 Ctlr-end, -PgDn, -Home, -PgUp AT имеет 84-ю клавишу, Sys Req, которая уникальна по своей функции. Клавиша предназначена для многопользовательских систем, как способ входа в главное меню системы. Когда клавиша нажимает- ся, в AX появляется код 8500H и выполняется прерывание 15H. При отпускании клавиши в AX появляется код 8501H, и опять же выпол- няется прерывание 15H. BIOS AT не обрабатывает функции 84H и 85H прерывания 15H, а просто делает возврат. Но можно программно заменить вектор прерывания для 15H, чтобы он указывал на процеду- ру обработки клавиши Sys Req. Такая процедура должна сначала прочитать AL, чтобы узнать была ли клавиша нажата (AL = 0) или отпущена (AL = 1). Заметим, что прерывание 15H предоставляет ряд процедур, некоторые из которых могут потребоваться программе обработки Sys Req. В этом случае процедура обработки Sys Req должна восстанавливать замененный ей вектор прерывания, и если в AH указаны функции отличные от 84H и 85H, то надо передать управ- ление оригинальному прерыванию 15H [1.2.4]. 3.2.5 Использование функциональных клавиш. 10 функциональных клавиш генерируют различные коды в сочетании с Shift, Ctrl и Alt, что обеспечивает 40 разных вариантов. Во всех случаях генерируется двухбайтный расширенный код, в котором первый байт всегда ASCII 0, а второй байт приведен в таблице: Коды Клавиши 59-68 F1-F10 84-93 Shift + F1-F10 94-103 Ctrl + F1-F10 104-113 Alt + F1-F10 Слишком много комбинаций с использованием функциональных клавиш могут смущать пользователя, но если Вам потребовалось еще 10 комбинаций, то можно использовать сочетание <ScrollLock> + <Fn>, как объяснено в [3.2.3]. Клавиатура PCjr имеет только 62 клавиши, по сравнению с 83 для IBM PC и XT, и 84 для AT. Некоторые комбинации с участием функ- циональных клавиш эмулируют часть недостающих клавиш, согласно следующей таблице: PCjr комбинации PC/XT/AT эквиваленты Fn + 1-0 F1-F10 Fn + B Break Fn + E Ctrl + PrtSc Fn + P Shift + PrtSc Fn + Q Ctrl + NumLock Fn + S ScrollLock Fn + CursorLeft PgUp Fn + CursorRight PgDn Fn + CursorUp Home Fn + CursorDown End Fn + - (скан-код серого минуса) Fn + = (скан-код серого плюса) Комбинации с участием клавиш-переключателей описаны в [3.2.2]. 3.2.6 Перепрограммирование отдельных клавиш. Под перепрограммированием клавиши понимается способ заставить ее выдавать другой код. Но к тому времени, когда программа полу- чает код нажатой клавиши, прерывание клавиатуры уже проинтерпре- тировало входящий скан-код и преобразовало его в некоторый зара- нее предопределенный код ASCII или расширенный код. К счастью, начиная с MS DOS версии 2.0, система содержит средства перепрог- раммирования клавиш. Это средство действует только если ввод воспринимается через функции DOS ввода с клавиатуры - функции прерывания BIOS 16H продолжают интерпретировать нажатия клавиш нормальным образом. Перепрограммирование доступно за счет Esc-последовательностей. Короткая строка, которая начинается с символа Esc (ASCII 27), предназначается для вывода на "стандартное устройство вывода", т.е. на терминал. Но благодаря наличию кода Esc символы даже не достигают монитора. Вместо этого такая строка заставляет MS DOS по другому интерпретировать клавишу, указанную в этой строке. Каждое изменение клавиши требует собственной строки, при этом один и тот же код может присваиваться какому угодно количеству клавиш. Общий вид такой строки такой: она начинается с кода Esc (ASCII 27), за которым идет [, затем номер кода переопределяемой клави- ши, затем точка с запятой (;), затем новый номер кода, присваива- емый клавише и, наконец, символ p. Таким образом, строка 27,'[65;97p' меняет A (ASCII 65) на a (ASCII 97). Расширенные коды записываются с указанием обоих байтов, причем за первым нулевым байтом должны стоять точка с запятой. Строка 27,'[0;68;0;83p' присваивает клавише F10 (0;68) тот же код, что и клавише Delete (0;83). Вы можете присваивать только расширенные коды, приведенные в таблице расширенных кодов [3.3.5]. Имеется несколько вариантов допустимого вида строки. Во-пер- вых, символьные клавиши могут обозначаться самим символом, заклю- ченным в кавычки. Таким образом, строка 27,'["A";"a"p' также меняет A на a. Во-вторых клавише может быть присвоена целая стро- ка символов, путем указания символов или их кодовых номеров в выражении. Строка 27,'["A";"A is for Apple"p' приведет к тому, что при нажатии на клавишу A в верхнем регистре, будет печататься вся строчка A is for Apple. На самом деле эти Esc-последователь- ности - ничего более, чем строки, в которых первый код или символ указывает какую клавишу нужно переопределить, а оставшаяся часть строки указывает какое значение Вы хотите ей придать. Помните, что номера кодов должны быть всегда разделены точкой с запятой, а символы заключены в кавычки. Коды и символы могут быть перемешаны в любых сочетаниях. Для того чтобы такие переопределения клавиш были возможны, необходимо чтобы драйвер ANSI.SYS был загружен при загрузке операционной системы. В противном случае Esc-последова- тельности будут игнорироваться. В приложении Д показано как это делается. Некоторые аспекты функционирования клавиатуры программируются на PCjr и AT. Процедуры доступные для AT интересны в основном для системных программистов; поскольку они нужны весьма немногим и достаточно сложны, то мы не будем рассматривать их здесь. При необходимости Вам придется обратиться к Техническому руководству по AT. В случае PCjr прерывание BIOS 16H имеет две дополнительные функции (AH = 3 и AH = 4), первая из которых устанавливает часто- ту автоповтора. "Частота автоповтора" - это та частота, с которой клавиша посылает свой код, когда она постоянно держится нажатой. Вторая функция включает и выключает звуковое подтверждение нажа- тия клавиши. Для функции 3 надо поместить в AL 0, чтобы вернуться к частоте автоповтора, устанавливаемой по умолчанию, 1 - чтобы увеличить начальную задержку перед тем, как начинается режим автоповтора, 2 - чтобы уменьшить частоту автоповтора вдвое, 3 - чтобы установить свойства 1 и 2 вместе и 4 - выключить автоповтор вообще. Для функции 4, поместив в AL 1, Вы будете иметь звуковое подтверждение нажатия клавиши, а 0 - выключите его. Высокий уровень. К несчастью, операторы Бейсика PRINT и WRITE не работают с Esc-последовательностями. Программы на Бейсике должны включать простые ассемблерные подпрограммы, использующие прерывания вывода MS DOS, обсуждаемые ниже в части "Средний уровень". В приложении Г показано, как включить ассемблерные процедуры в программы на Бейсике. В приведенном примере предполагается, что процедура находится в памяти, начиная с адреса 2000:0000. Операторы DATA содержат ассемблерный код. В конце строки переопределения клавиши должен быть добавлен код $. 100 DATA &H55, &H8B, &HEC, &H8B, &H5E, &H06, &H8B, &H57 110 DATA &H01, &HB4, &H09, &HCD, &H21, &H5D, &HCA, &H02, &H00 120 'помещаем процедуру в память по адресу 2000:0000 130 DEF SEG = &H2000 'определяем сегмент 140 FOR N=0 TO 16 'процедура длиной 17 байт 150 READ Q 'читаем байт 160 POKE N,Q 'помещаем его в память 170 NEXT ' 180 ''' меняем A на a 190 Q$ = CHR$(27)+"[65;97p$" 'строка переопределения 200 ROUTINE = 0 'указываем на строку 210 CALL ROUTINE(Q$) 'вызываем процедуру Средний уровень. Используйте функцию 9 прерывания 21H для посылки строки на стандартное устройство вывода. DS:DX должны указывать на первый символ строки в памяти и строка должна завершаться символом $ (24H). Здесь F2 (0;60) переопределяется таким образом, чтобы она действовала как Del (0;83). ;---в сегменте данных CHANGE_KEY DB 27,'[0;60;0;83p$' ;---для изменения определения клавиши LEA DX,CHANGE_KEY ;DS:DX должны указывать на строку MOV AH,9 ;номер функции INT 21H ;переопределение клавиши 3.2.7 Создание макроопределений для отдельных клавиш. Макроопределение - это строка символов, которая будет выво- диться при нажатии одной клавиши. Макроопределения могут быть запрограммированы в интерпретаторе Бейсика или на уровне опера- ционной системы для уменьшения печатания. Поскольку строка может содержать управляющие коды, такие как символ возврата каретки (ASCII 13), то одно макроопределение может выполнять целый набор команд. Для ускорения разработки программ, например, можно напи- сать макроопределение, содержащее все необходимые команды, чтобы оттранслировать и скомпоновать определенную программу. Макроопределения, обеспечиваемые Бейсиком, работают как в Бейсиковских программах, так и на командном уровне Бейсика. Нап- ример, если Вы запрограммировали клавишу, чтобы при ее нажатии выводилось слово "Орангутан", то при нажатии этой клавиши функция INPUT получит всю эту строку, а цикл, включающий INKEY$, последо- вательно получит девять символов. С другой стороны, макроопреде- ления, созданные на уровне операционной системы, всегда работают на командном уровне DOS, но внутри программ они будут работать только если программа для ввода с клавиатуры использует функции DOS. Поскольку большинство коммерческих программных продуктов используют прерывание BIOS 16H, то для этих программ макроопреде- ления не будут работать. Конечно, средства для создания макрооп- ределений могут быть вставлены в процедуры ввода с клавиатуры. Например, чтобы позволить пользователю программы создать макрооп- ределение для F1, запросив строку и поместив ее в MACRO1$, надо на Бейсике написать что-то вроде: 1000 '''процедура ввода расширенного кода, в C - 2-й байт кода 1010 IF C=59 THEN LOCATE X,Y: PRINT MACRO1$ Высокий уровень. Бейсик имеет встроенный механизм создания макроопределений, но он позволяет программировать только 10 функциональных клавиш, а строки должны быть не длиннее 15 символов. Бейсик рассматривает функциональные клавиши, как программируемые клавиши. Оператор KEY присваивает макроопределение данной клавише. Строка KEY 5,"END" приводит к тому, что функциональная клавиша #5 будет посылать слово END в текущую позицию курсора на экране. Символы составляющие строку могут вводиться как строки симво- лов, как ASCII коды (используя CHR$) или как комбинация того и другого. Команды KEY 5,"A" и KEY 5,CHR$(65) эквивалентны. Для того, чтобы строка сразу исполнялась надо добавить в конце строки символ возврата каретки (ASCII 13). Команда FILES, выводящая каталог диска, исполняется после того, как Вы присвоите это зна- чение F1 командой KEY 1,"FILES"+CHR$(13). Бейсик присваивает десяти функциональным клавишам распростра- ненные операторы Бейсика. Вы можете отменить макроопределение для данной клавиши, присвоив ей пустую строку,например, команда KEY 1,"" приведет к тому, что при нажатии F1 ничего вводиться не будет. Первые шесть символов каждой строки автоматически выводят- ся в нижней части экрана интерпретатором Бейсика. Вы можете уп- равлять наличием этого вывода используя команды KEY ON и KEY OFF. Для того чтобы вывести на экран полные определения клавиш, введи- те команду KEY LIST. Вот несколько примеров: KEY 1,"ERASE" ; теперь F1 выводит "ERASE" KEY 10,"LIST"+CHR$(13) ; теперь F10 выдает листинг KEY 7,"" ; теперь F7 ничего не выдает KEY OFF ; подавляет вывод внизу экрана KEY ON ; включает вывод внизу экрана KEY LIST ; выдает список значений 10 клавиш Для создания макроопределений других клавиш в Бейсике, Вы должны использовать средства MS DOS, описанные в [3.2.6]. Средний уровень. В MS DOS макроопределения создаются с помощью метода перепрог- раммирования клавиш, описанного в [3.2.6]. Единственное отличие в том, что клавише сопоставляется целая строка символов. Строка может быть введена в виде символов, заключенных в кавычки, или в виде кодов или комбинации того и другого. Вот несколько примеров: 27,'["A";"SET"p' ; присваивает SET заглавной A 27,'["ASET"p' ; эквивалентно предыдущему 27,'[27;"dir";13p' ; присваивает dir<CR> клавише Esc 27,'[0;59;"copy *.* b:";13p' ;присваивает F1 команду 27,'[0;68;0;72;0;72;0;72p' ;заставляет F10 сдвинуть курсор на ;три строки вверх 3.2.8 Создание процедуры обработки Ctrl-Break. Когда вводится комбинация Ctrl-Break, то прерывание клавиатуры устанавливает флаг, указывающий что должна быть выполнена проце- дура обработки Ctrl-Break. Управление передается этой процедуре только в тот момент, когда программа использует функцию DOS, способную распознавать этот флаг. Обычно только стандартные функ- ции ввода/вывода MS DOS могут распознавать этот флаг (функции от 1 до C прерывания 21H, за исключением функций 6 и 7). Но поместив строку BREAK=ON либо в файл AUTOEXEC.BAT, либо в CONFIG.SYS, используемые MS DOS при старте системы, Вы получите ситуацию, когда обращение к любой функции DOS приведет к вызову процедуры обработки Ctrl-Break. При этом выполнение программы будет немного замедлено. Процедура обработки Ctrl-Break дает возможность завершить программу в любой момент времени. Когда функция DOS распознает статус Ctrl-Break, то управление передается процедуре, на которую указывает вектор прерывания 23H. DOS использует эту процедуру для завершения работающей программы. Но процедура может быть перепи- сана Вами, с тем чтобы она удовлетворяла любым Вашим требованиям. Эта процедура должна быть программируемой, с тем чтобы перед завершением программы могли быть выполнены все критические опера- ции. Может требоваться выравнивание стека, с тем чтобы SP указы- вал на второе слово от вершины (первое слово для программ COM) перед выполнением завершающей инструкции RET. Вектора прерывания, измененные программой должны быть восстановлены, а все открытые устройства ввода/вывода - закрыты. Если были запрещены прерыва- ния, то надо разрешить их. Все это должно обеспечить машине воз- можность нормально работать со следующей программой после завер- шения программы по Ctrl-Break. Другая альтернатива - сделать процедуру обработки Ctrl-Break, состоящей из одной инструкции IRET, что запрещает завершение программы таким способом. Средний уровень. В данном примере выход из программы происходит после выравни- вания стека. Процедура кончается инструкцией RET, а не IRET, поскольку в данном случае она действует в точности так же, как и инструкция RET при нормальном завершении программы. В момент, когда она используется, указатель стека (SP) должен указывать на второе слово стека. Это предполагает, что программа в форме EXE. Помните, что стек помещаает свое первое слово в самую старшую ячейку памяти, второе - в ячейку ниже, и т.д. Если размер стека 400 байт, то надо установить SP на 396. Для программ COM надо устанавливать указатель стека на первое слово стека или просто завершать процедуру обработки Ctrl-Break прерыванием 21H. ;---это новая процедура обработки Ctrl-Break C_B PROC FAR MOV AX,396 ;значение для второго слова стека MOV SP,AX ;выравниваем указатель стека RET ;возврат в DOS C_B ENDP ; ;---изменение вектора прерывания PUSH DS ;сохраняем регистр MOV AX,SEG C_B ;готовим адрес процедуры MOV DS,AX ; MOV DX,OFFSET C_B ; MOV AH,25H ;номер функции MOV AL,23H ;номер вектора INT 21H ;изменяем вектор POP DS ;восстанавливаем регистр Программа может в любое время проверить был ли сделан запрос на выполнение процедуры обработки Ctrl-Break. Надо поместить в AL 0 и вызвать функцию 33 прерывания 21H. При возврате DL будет содержать 1, если был установлен флаг прерывания по Ctrl-Break, и 0 - в противном случае. Если при вызове поместить в AL 1, то статус будет установлен. В этом случае, перед вызовом функции, поместите в DL 0 или 1, чтобы флаг был установлен или очищен. 3.2.9 Перепрограммирование клавиши PrtSc. Клавиша PrtSc выдает звездочку (ASCII 42), если нажать ее одну, она выдает расширенный код 114, если нажать ее вместе с клавишей Ctrl. Но комбинация <Shift> + <PrtSc> имеет совершенно отдельный статус. Нажатие на другие клавиши заставляют прерывание клавиатуры помещать их коды в буфер клавиатуры (или, для кла- виш-переключателей, записывать их состояние [3.1.7]). Нажатие клавиши не влияет на выполняемую программу, до тех пор пока прог- рамма не станет считывать символ клавиши из буфера клавиатуры. Но комбинация <Shift> + <PrtSc> заставляет прерывание клавиатуры немедленно передать управление процедуре, на которую указывает вектор прерывания 5. В некотьором смысле она работает как аппа- ратное прерывание. Прерывание 5 запрограммировано таким образом, чтобы выдать содержимое экрана на принтер. Но вектор прерывания может указы- вать на процедуру, предназначенную для совершенно другой цели. Например, изощренная программа имитации, которой требуются часы для завершения своей работы, может прервана в любое время комби- нацией Shift + PrtSc, чтобы она выдала рапорт о текущем состоянии расчетов. Вам может также захотеться, чтобы на принтер можно было посылать копию графического экрана. Другая возможность, использо- вать PrtSc как способ доступа к программе, которая находится резидентно в памяти во время загрузки MS DOS [1.3.4]. Такая стра- тегия позволит Вам написать утилиту, которая может работать из другого программного обеспечения. Низкий уровень. Здесь приведена основная форма перепрограммирования процедуры. Не забудьте восстановить оригинальный вектор прерывания (F000:FF54) при завершении программы. Если Вы забудете сделать это, то все будет идти нормально, до тех пор пока не будет нажата комбинация Shift + PrtSc, а тогда произойдет крах системы (более полный пример программирования прерывания см. в [1.2.3]). ;---изменить вектор прерывания для PrtSc CLI ;запрет прерываний MOV AX,SEG NEW_ROUTINE ;получаем адрес процедуры MOV DS,AX ; MOV DX,OFFSET NEW_ROUTINE ; MOV AL,5 ;номер изменяемого вектора MOV AH,25H ;номер функции INT 21H ;изменяем вектор STI ;разрешаем прерывания . . ;---описание процедуры PrtSc NEW_ROUTINE PROC FAR STI ;разрешаем прерывания PUSH AX ;сохраняем регистры . . MOV CX,100 ;Ваша процедура . . POP AX ;восстанавливаем регистры IRET ;возврат из прерывания NEW_ROUTINE ENDP ; Раздел 3. Сводка кодов клавиш и применений. Различные коды клавиш и коды символов могут приводить к недо- разумениям. В нижеприведенных таблицах все они перечислены. Обра- тите внимание на следующие аномалии: - клавиша Ins является единственной, которая при нажатии, как выдает код символа в буфер клавиатуры, так и меняет статус ре- гистра клавиш-переключателей. - имеется 4 кода ASCII, которые могут быть получены двумя способами. ASCII 8 - нажатием клавиши BackSpace и Ctrl-H, ASCII 9 - клавиши Tab и Ctrl-I, ASCII 13 - клавиши Enter и Ctrl-M, а ASCII 27 - клавиши Esc и Ctrl-[. - символы, соответствующие 32 управляющим кодам ASCII не выво- дятся на экран, при использовании функций ввода с клавиатуры, обеспечивающих автоматическое эхо. Они могут быть выведены либо с помощью функции 10H прерывания 10H, либо прямым выводом в память дисплея (оба способа обсуждаются в [4.3.1]). - комбинации клавиши Ctrl с буквами алфавита генерируют одно- байтные коды ASCII. Все остальные комбинации Ctrl генерируют двухбайтные (расширенные) коды. - клавиша <5> дополнительной клавиатуры не действует, если установлен режим управления курсором клавишей NumLock. - комбинации Shift-PrtSc и Ctrl-Alt (а также SysReq для AT) это единственные случаи, когда комбинация клавиш приводит к не- медленному вызову некоторой процедуры. Из них только первая пе- репрограммируема. Прерывание обработки Ctrl-Break (также переп- рограммируемое) вызывается только тогда, когда статус Ctrl-Break будет обнаружен процедурой MS DOS. - любой код ASCII, кроме 0, может быть введен путем нажатия клавиши Alt, набора кода ASCII на дополнительной клавиатуре и, затем, отпускания клавиши Alt. Поскольку код 0 исключен, то рас- ширенные коды не могут быть введены таким способом. Отметим, что Вы практически ничего не можете сделать, чтобы прео- долеть ограничения, накладываемые на недопустимые комбинации клавиш. Например, Вы не можете определить комбинацию Ctrl + Cur- sorUp, принимая код CursorUp, а затем проверяя регистр статуса перключателей для определения того, была ли нажата клавиша Ctrl. Если Ctrl была нажата, то клавиша CursorUp вообще не выдает ника- кого кода. 3.3.1 Предопределенное использование клавиш. Имеется ряд соглашений относительно использования клавиш, которые должны выполняться всеми программами. Они описаны в Тех- ническом руководстве и если программисты будут придерживаться их, то пользователю будет легко переходить от одной программы к дру- гой. Заметим, однако, что программное обеспечение самой фирмы IBM не всегда следует этим соглашениям. Они таковы: ScrollLock Переключает режим вывода на терминал, при котором перемещение курсора сдвигает экран, а не сам курсор CTRL 4/6 Сдвигает курсор на слово влево/вправо. Другая возможность: горизонтальный сдвиг экрана на позицию табуляции влево/вправо. Pg Up Возврат на 25 строк назад. Pg Dn Сдвиг на 25 строк вперед. CTRL END Удаление текста от позиции курсора до конца строки. CTRL PgDn Удаление текста от позиции курсора до конца экрана. HOME В тексте перемещает курсор к началу строки или документа. В меню - возвращает в главное меню. CTRL HOME Чистит экран и помещает курсор в левый верхний угол. END Перемещает курсор к концу строки или к концу документа. BACKSPACE/DELETE DELETE уничтожает символ, на который указы- вает курсор, и сдвигает остаток строки на одну позицию влево. BACKSPACE удаляет символ слева от курсора и делает то же самое. INS Переключает режим вставки/замены. TAB/BACKTAB Перемещает курсор в следующую позицию табу- ляции, вправо - если была нажата одна и влево - если вместе с клавишей Shift. ESC Выход из программы или процедуры. 3.3.2 Сводная таблица скан-кодов. Каждая клавиша генерирует два типа скан-кодов, "код нажатия" - когда клавиша нажимается, и "код освобождения" - когда клавиша отпускается. Для всех машин, кроме AT, код освобождения на 128 больше кода нажатия (бит 7 = 1). Таким образом клавиша T создает код 20 при нажатии и код 148 при отпускании. AT использует одну и ту же цепочку битов для кодов нажатия и освобождения, но коды освобождения состоят из двух байтов, первый из которых всегда равен 0F0H. PCjr имеет специальный скан-код мнимой клавиши, номер 55. Этот код порождается, когда были одновременно нажаты три или более клавиш, что помогает избежать ошибок при вводе. Прерывание клавиатуры отбрасывает этот код и он не связывается ни с каким кодом ASCII или расширенным кодом. Клавиши пишущей машинки Клавиша Код нажатия Клавиша Код нажатия Клавиша Код нажатия "1" 2 "T" 20 "L" 38 "2" 3 "Y" 21 ";" 39 "3" 4 "U" 22 "'" 40 "4" 5 "I" 23 "`" 41 "5" 6 "O" 24 "\" 43 "6" 7 "P" 25 "Z" 44 "7" 8 "[" 26 "X" 45 "8" 9 "]" 27 "C" 46 "9" 10 "A" 30 "V" 47 "0" 11 "S" 31 "B" 48 "-" 12 "D" 32 "N" 49 "=" 13 "F" 33 "M" 50 "Q" 16 "G" 34 "," 51 "W" 17 "H" 35 "." 52 "E" 18 "J" 36 "/" 53 "R" 19 "K" 37 пробел 57 Управляющие клавиши Esc - 1 Ctrl - 29 Alt - 56 BackSpace - 14 left shift - 42 CapsLock - 58 Tab - 15 right shift - 42 NumLock - 58 Enter - 28 PrtSc - 55 ScrollLock - 70 Функциональные клавиши F1 - 59 F5 - 63 F9 - 67 F2 - 60 F6 - 64 F10 - 68 F3 - 61 F7 - 65 F4 - 62 F8 - 66 Клавиши дополнительной клавиатуры "7" - 71 "5" - 76 "3" - 81 "8" - 72 "6" - 77 "0" - 82 "9" - 73 "+" - 78 "." - 83 "-" - 74 "1" - 79 Sys Req - 132 (только AT) "4" - 75 "2" - 80 мнимая - 55 (только PCjr) 3.3.3 Сводная таблица кодов ASCII Номера кодов от 0 до 31, управляющих кодов, объяснены более детально в [7.1.9]. Напоминаем, что любой код ASCII от 1 до 255 может быть введен с клавиатуры, если держать нажатой клавишу Alt при наборе номера кода на дополнительной клавиатуре (с соответст- венно установленным режимом NumLock). Когда клавиша Alt затем освобождается, то код вводится. Символ 10-ный 16-ричный двоичный Символ 10-ный 16-ричный двоичный (null) 0 00 00000000 0 48 30 00110000 1 01 00000001 1 49 31 00110001 2 02 00000010 2 50 32 00110010 3 03 00000011 3 51 33 00110011 4 04 00000100 4 52 34 00110100 5 05 00000101 5 53 35 00110101 6 06 00000110 6 54 36 00110110 7 07 00000111 7 55 37 00110111 8 08 00001000 8 56 38 00111000 9 09 00001001 9 57 39 00111001 10 0A 00001010 : 58 3A 00111010 11 0B 00001011 ; 59 3B 00111011 12 0C 00001100 < 60 3C 00111100 13 0D 00001101 = 61 3D 00111101 14 0E 00001110 > 62 3E 00111110 15 0F 00001111 ? 63 3F 00111111 16 10 00010000 @ 64 40 01000000 17 11 00010001 A 65 41 01000001 18 12 00010010 B 66 42 01000010 19 13 00010011 C 67 43 01000011 20 14 00010100 D 68 44 01000100 21 15 00010101 E 69 45 01000101 22 16 00010110 F 70 46 01000110 23 17 00010111 G 71 47 01000111 24 18 00011000 H 72 48 01001000 25 19 00011001 I 73 49 01001001 26 1A 00011010 J 74 4A 01001010 27 1B 00011011 K 75 4B 01001011 28 1C 00011100 L 76 4C 01001100 29 1D 00011101 M 77 4D 01001101 30 1E 00011110 N 78 4E 01001110 31 1F 00011111 O 79 4F 01001111 пробел 32 20 00100000 P 80 50 01010000 ! 33 21 00100001 Q 81 51 01010001 " 34 22 00100010 R 82 52 01010010 # 35 23 00100011 S 83 53 01010011 $ 36 24 00100100 T 84 54 01010100 % 37 25 00100101 U 85 55 01010101 & 38 26 00100110 V 86 56 01010110 ' 39 27 00100111 W 87 57 01010111 ( 40 28 00101000 X 88 58 01011000 ) 41 29 00101001 Y 89 59 01011001 * 42 2A 00101010 Z 90 5A 01011010 + 43 2B 00101011 [ 91 5B 01011011 , 44 2C 00101100 \ 92 5C 01011100 - 45 2D 00101101 ] 93 5D 01011101 . 46 2E 00101110 ^ 94 5E 01011110 / 47 2F 00101111 _ 95 5F 01011111 Символ 10-ный 16-ричный двоичный Символ 10-ный 16-ричный двоичный ` 96 60 01100000 Щ 153 99 10011001 a 97 61 01100001 Ъ 154 9A 10011010 b 98 62 01100010 Ы 155 9B 10011011 c 99 63 01100011 Ь 156 9C 10011100 d 100 64 01100100 Э 157 9D 10011101 e 101 65 01100101 Ю 158 9E 10011110 f 102 66 01100110 Я 159 9F 10011111 g 103 67 01100111 а 160 A0 10100000 h 104 68 01101000 б 161 A1 10100001 i 105 69 01101001 в 162 A2 10100010 j 106 6A 01101010 г 163 A3 10100011 k 107 6B 01101011 д 164 A4 10100100 l 108 6C 01101100 е 165 A5 10100101 m 109 6D 01101101 ж 166 A6 10100110 n 110 6E 01101110 з 167 A7 10100111 o 111 6F 01101111 и 168 A8 10101000 p 112 70 01110000 й 169 A9 10101001 q 113 71 01110001 к 170 AA 10101010 r 114 72 01110010 л 171 AB 10101011 s 115 73 01110011 м 172 AC 10101100 t 116 74 01110100 н 173 AD 10101101 u 117 75 01110101 о 174 AE 10101110 v 118 76 01110110 п 175 AF 10101111 w 119 77 01110111 ░ 176 B0 10110000 x 120 78 01111000 ▒ 177 B1 10110001 y 121 79 01111001 ▓ 178 B2 10110010 z 122 7A 01111010 │ 179 B3 10110011 { 123 7B 01111011 ┤ 180 B4 10110100 | 124 7C 01111100 ╡ 181 B5 10110101 } 125 7D 01111101 ╢ 182 B6 10110110 ~ 126 7E 01111110 ╖ 183 B7 10110111 127 7F 01111111 ╕ 184 B8 10111000 А 128 80 10000000 ╣ 185 B9 10111001 Б 129 81 10000001 ║ 186 BA 10111010 В 130 82 10000010 ╗ 187 BB 10111011 Г 131 83 10000011 ╝ 188 BC 10111100 Д 132 84 10000100 ╜ 189