только одному - из байтов статуса. Это байт по адресу 0040:0017,
который содержит больше полезной информации. Байт возвращается в
AL.

;---проверка статуса клавиши вставки
MOV AH,2 ;номер функции
INT 16H ;получаем байт статуса
TEST AL,10000000B ;проверяем бит 7
JZ INSERT_OFF ;если 0, то INSERT выключен

Низкий уровень.

В данном примере устанавливается режим вставки, за счет уста-
новки бита 7 байта статуса по адресу 0040:0017 (который адресует-
ся как 0000:0417).

SUB AX,AX ;устанавливаем добавочный сегмент на
MOV ES,AX ;начало памяти
MOV AL,10000000B ;готовим бит 7 к установке
OR ES:[417H],AL ;меняем байт статуса



    3.1.8 Написание процедуры ввода с клавиатуры общего назначения.



Система кодов, используемых клавиатурой, не поддается простой
интрепретации. Коды могут иметь длину 1 или 2 байта и нет просто-
го соответствия между длиной кода и тем, служит ли он для обозна-
чения символа или для управления оборудованием. Не все комбинации
клавиш даже выдают уникальный код, поэтому необходимы добавочные
усилия, чтобы различить их. Ни коды ASCII, ни расширенные коды не
упорядочены таким образом, который бы позволил их простую группи-
ровку и проверку ошибок. Другими словами, процедура ввода с кла-
виатуры общего назначения требует хлопотливого программирования.
Здесь приведены примеры на Бейсике и с использованием прерыва-
ния 16H. В них показано как свести вместе большинство информации,
приведенной в данной главе. Общий алгоритм показан на рис. 3-3.

Высокий уровень.

Процедура обработки ввода с клавиатуры, написанная на Бейсике,
может делать все что делает ассемблерная процедура, за одним
исключением. Функция INKEY$ не предоставляет доступа к скан-ко-
дам. Это означает, что Вы не можете сказать получены ли коды
ASCII 8, 9, 13 и 27 от нажатия клавиш <BackSpace>, <Tab>, <Enter>
и <Escape> или через Ctrl-H, -I, -M и -[. Различие может быть
установлено проверкой бита статуса клавиши Ctrl, по адресу
0040:0017, в момент нажатия клавиши. Но этот метод не будет рабо-
тать, если введенный символ был запасен в буфере клавиатуры в
течение некоторого времени.

100 C$=INKEY$:IF C$="" THEN 100 'получение символа
110 IF LEN(C$)=2 THEN 700 'если расширенный, то на 700
120 C=ASC(C$) 'иначе берем номер кода ASCII
130 IF C<32 THEN 300 'если управляющий, то на 300
140 IF C<65 OR C>123 THEN 100 'принимаем только символы
150 '''пишущей машинки и делаем с ними, что хотим, например:
160 S$=S$+C$ 'добавляем символ к строке
170 PRINT C$; 'выводим его на экран
180 '''... и т.д.
190 GOTO 100 'на ввод следующего символа
.
.
300 '''процедура обработки управляющих кодов ASCII
310 DEF SEG = 0 'указываем на начало памяти
320 REGISTER=PEEK(&H417) 'берем регистр статуса
330 X=REGISTER AND 4 'X=4, когда нажат Ctrl
340 IF X=0 THEN 500 'если не нажат, то на 500
350 '''если это комбинация Ctrl-буква, то делаем что хотим
360 IF C=8 THEN GOSUB 12000 'например, переходим на проце-
370 '''дуру вывода экрана помощи и т.д.
380 GOTO 100 'на ввод следующего символа
.
.


500 '''процедура обработки 4-х клавиш: декодирует коды ASCII 8,
510 '''9, 13 и 27, когда клавиша Ctrl не нажата
520 IF C=8 THEN GOSUB 5000 'обработка <BackSpace>
530 IF C=9 THEN GOSUB 6000 'обработка <Tab>
540 IF C=13 THEN GOSUB 7000 'обработка <CR>
550 IF C=27 THEN GOSUB 8000 'обработка <Esc>
560 GOTO 100 'на ввод следующего символа
.
.
700 '''процедура обработки расширенных кодов
710 C$=RIGHT$(C$,1) 'берем только 2-й байт C$
720 C=ASC(C$) 'переводим в числовую форму
730 '''в C - расширенный код - делаем с ним, что хотим, например
740 IF C<71 OR C>81 THEN 100 'берем только управление курсором
750 IF C=72 THEN GOSUB 3500 'обработка "курсор-вверх"
760 '''... и т.д.
770 GOTO 100 'на ввод следующего символа

Средний уровень.

Этот пример отличается от предыдущего методом распознавания
четырех частных случаев Ctrl-H, -I, -M и -[. Здесь, когда встает
вопрос о том, возник ли указанный код при нажатии одной клавиши,
или в комбинации с клавишей Ctrl, проверяется скан-код. Этот
метод более правилен, чем проверка бита статуса, так как скан-код
запоминается в буфере клавиатуры, а установка бита статуса может
быть изменена.

;---получение кода нажатой клавиши и определение его типа
NEXT: MOV AH,0 ;функция ввода с клавиатуры BIOS
INT 16H ;получаем введенный код
CMP AL,0 ;проверка на расширенный код
JE EXTENDED_CODE ;если да, то на спец. процедуру
CMP AL,32 ;проверка на управляющий символ
JL CONTROL_CODE ;если да, то на спец. процедуру
CMP AL,65 ;если символ не входит в набор пишу-
JL NEXT ;щей машинки, то берем следующий
CMP AL,123 ;
JL NEXT ;
;---теперь обрабатываем символ в AL
STOSB ;запоминаем символ по адресу ES:DI
MOV AH,2 ;функция вывода символа на экран
MOV DL,AL ;помещаем символ в DL перед выводом
INT 21H ;выводим его на экран
.
.
JMP NEXT ;переходим к следующему символу


;---анализируем управляющие коды
CONTROL_CODE: CMP AL,13 ;код ASCII 13?
JNE TAB ;если нет, то след. проверка
CMP AH,28 ;иначе проверяем скан-код <CR>
JNE C_M ;если нет, то было Ctrl-M
CALL CARRIAGE_RET;обработка возврата каретки
JMP NEXT ;переход к следующему символу
C_M: CALL CTRL_M ;обработка Ctrl-M
JMP NEXT ;переход к следующему символу
TAB: CMP AL,9 ;проверка на табуляцию...
.
.
CMP AL,10 ;затем проверка других
.
.
REJECT: JMP NEXT ;переход к следующему символу
;---анализ расширенных кодов (2-й байт кода в AH):
EXTENDED_CODE: CMP AH,71 ;проверка нижней границы
JL REJECT ;если меньше, то след. символ
CMP AH,81 ;проверка верхней границы
JL REJECT ;если больше, то след. символ
;---AH содержит символ управления курсором, анализируем его:
CMP AH,72 ;"курсор-вверх"?
JE C_U ;если да, то на процедуру
CMP AH,80 ;"курсор-вниз"?
JE C_D ;если да, то на процедуру
.
.
C_U: CALL CURSOR_UP ;вызов соответствующей процедуры
JMP NEXT ;переход к следующему символу
C_D: CALL CURSOR_DOWN ;вызов соответствующей процедуры
JMP NEXT ;переход к следующему символу



    3.1.9 Перепрограммирование прерывания клавиатуры.



Когда микропроцессор клавиатуры помещает скан-код в порт A
микросхемы 8255 (адрес порта 60H - см. [1.1.1]), то при этом
вызывается прерывание 9. Задача этого прерывания - преобразовать
скан-код символа, основываясь на состоянии клавиш-переключателей,
и поместить его в буфер клавиатуры. (Если скан-код соответствует
клавише-переключателю, то в буфер клавиатуры не пишется ничего,
за исключением случая клавиши <Ins>, а вместо этого прерывание
изменяет байты статуса, расположенные в области данных BIOS
[3.1.7]). Прерывания "ввода с клавиатуры" DOS и BIOS на самом
деле всего лишь прерывания "ввода из буфера клавиатуры". На самом
деле они не распознают нажатия клавиш. Точнее, они читают интерп-
ретацию введенных клавиш, которую обеспечило прерывание 9. Заме-
тим, что PCjr использует специальную процедуру (INT 48H) для
преобразования ввода от его 62 клавиш к 83-клавишному протоколу,
используемому другими IBM PC. Результат этой процедуры передается
прерыванию 9, которое выполняет свою работу как обычно. Прерыва-
нием 49H PCjr обеспечивает специальные неклавишные скан-коды,
которые потенциально могут устанавливаться периферийными уст-
ройствами, использующими инфракрасную (беспроволочную) связь с
клавиатурой.
Требуется весьма необычное применение, чтобы имело смысл пе-
репрограммировать это прерывание, особенно учитывая, что MS DOS
позволяет Вам перепрограммировать любую клавишу клавиатуры
[3.2.6]. Если все же Вам придется перепрограммировать прерывание
9, то эта глава даст Вам основы для старта. Сначала надо прочи-
тать [1.2.3], чтобы понимать как программируются прерывания. В
прерывании клавиатуры можно выделить три основных шага:

1. Прочитать скан-код и послать клавиатуре подтвердающий сиг-
нал.
2. Преобразовать скан-код в номер кода или в установку оегист-
ра статуса клавиш-переключателей.
3. Поместить код клавиши в буфер клавиатуры.

В момент вызова прерывания скан-код будет находиться в порте
A. Поэтому сначала надо этот код прочитать и сохранить на стеке.
Затем используется порт B (адрес 61H), чтобы быстро послать сиг-
нал подтверждения микропроцессору клавиатуры. Надо просто устано-
вить бит 7 в 1, а затем сразу изменить его назад в 0. Заметим,
что бит 6 порта B управляет сигналом часов клавиатуры. Он всегда
должен быть установлен в 1, иначе клавиатура будет выключена. Эти
адреса портов применимы и к AT, хотя он и не имеет микросхемы
интерфейса с периферией 8255.
Сначала скан-код анализируется на предмет того, была ли клави-
ша нажата (код нажатия) или отпущена (код освобождения). На всех
машинах, кроме AT, код освобождения индицируется установкой бита
7 скан-кода в 1. Для AT, у которого бит 7 всегда равен 0, код
освобождения состоит из двух байтов: сначала 0F0H, а затем
скан-код. Все коды освобождения отбрасываются, кроме случая кла-
виш-переключателей, для которых делаются соответствующие измене-
ния в байтах их статуса. С другой стороны, все коды нажатия обра-
батываются. При этом опять могут изменяться байты статуса кла-


виш-переключателей. В случае же символьных кодов, надо проверять
байты статуса, чтобы определить, например, что скан-код 30 соот-
ветствует нижнему или верхнему регистру буквы A.
После того как введенный символ идентифицирован, процедура
ввода с клавиатуры должна найти соответствующий ему код ASCII или
расширенный код. Приведенный пример слишком короток, чтобы рас-
смотреть все случаи. В общем случае скан-коды сопоставляются
элементам таблицы данных, которая анализируется инструкцией XLAT.
XLAT принимает в AL число от 0 до 255, а возвращает в AL 1-байт-
ное значение из 256-байтной таблицы, на которую указывает DS:BX.
Таблица может находиться в сегменте данных. Если в AL находился
скан-код 30, то туда будет помещен из таблицы байт номер 30 (31-й
байт, так как отсчет начинается с нуля). Этот байт в таблице
должен быть установлен равным 97, давая код ASCII для "a". Конеч-
но для получения заглавной A нужна другая таблица, к которой
обращение будет происходить, если статус сдвига установлен. Или
заглавные буквы могут храниться в другой части той же таблицы, но
в этом случае к скан-коду надо будет добавлять смещение, опреде-
ляемое статусом клавиш-переключателей.
Наконец, номера кодов должны быть помещены в буфер клавиатуры.
Процедура должна сначала проверить, имеется ли в буфере место для
следующего символа. В [3.1.1] показано, что этот буфер устроен
как циклическая очередь. Ячейка памяти 0040:001A содержит указа-
тель на голову буфера, а 0040:001C - указатель на хвост. Эти
словные указатели дают смещение в области данных BIOS (которая
начинается в сегменте 40H) и находятся в диапазоне от 30 до 60.
Новые символы вставляются в ячейки буфера с более старшими адре-
сами, а когда достигнута верхняя граница, то следующий символ
переносится в нижний конец буфера. Когда буфер полон, то указа-
тель хвоста на 2 меньше указателя на голову - кроме случая, когда
указатель на голову равен 30 (начало области буфера), а в этом
случае буфер полон, когда указатель хвоста равен 60.
Для вставки символа в буфер, надо поместить его в позицию, на
которую указывает хвост буфера и затем увеличить указатель хвоста
на 2; если указатель хвоста был равен 60, то надо изменить его
значение на 30. Вот и все. Схема прерывания клавиатуры показана
на рис. 3-4.

Низкий уровень.

Эффективная процедура требует глубокого продумывания. В этом
примере даны только самые зачатки. Он принимает только буквы на
нижнем и верхнем регистрах, причем все они загружены в одну таб-
лицу, в которой буквы верхнего регистра находятся на 100 байт
выше, чем их младшие братья. Анализируется только левая клавиша
сдвига и текущее состояние клавиши CapsLock игнорируется.

;---в сегменте данных
TABLE DB 16 DUP(0) ;пропускаем 1-е 16 байт
DB 'qwertyuiop',0,0,0,0 ;верхний ряд клавиатуры
DB 'asdfghjkl',0,0,0,0,0 ;средний ряд клавиатуры
DB 'zxcvbnm' ;нижний ряд клавиатуры
DB 16 DUP(0) ;пропуск до верхнего регистра
DB 'QWERTYUIOP',0,0,0,0 ;те же символы на верхнем
DB 'ASDFGHJKL',0,0,0,0,0 ;регистре
DB 'ZXCVBNM' ;


;---в начале программы устанавливаем прерывание
CLI ;запрет прерываний
PUSH DS ;сохраняем регистр
MOV AX,SEG NEW_KEYBOARD ;DS:DX должны указывать на
MOV DS,AX ;процедуру обработки
MOV DX,OFFSET NEW_KEYBOARD ;прерывания
MOV AL,9 ;номер вектора прерывания
MOV AH,25H ;номер функции DOS
INT 21H ;меняем вектор прерывания
POP DS ;восстанавливаем регистр
STI ;разрешаем прерывания

Программа продолжается, затем оставаясь резидентной [1.3.4].

;---это само прерывание клавиатуры
NEW_KEYBOARD PROC FAR ;сохраняем все изменяемые
PUSH AX ;регистры
PUSH BX ;
PUSH CX ;
PUSH DI ;
PUSH ES ;
;---получаем скан-код и посылаем сигнал подтверждения
IN AL,60H ;получаем скан-код из порта A
MOV AH,AL ;помещаем копию в AH
PUSH AX ;сохраняем скан-код
IN AL,61H ;читаем состояние порта B
OR AL,10000000B ;устанавливаем бит 7
OUT 61H,AL ;посылаем измененный байт в порт
AND AL,01111111B ;сбрасываем бит 7
OUT 61H,AL ;возвращаем состояние порта B
;---ES должен указывать на область данных BIOS
MOV AX,40H ;устанавливаем сегмент
MOV ES,AX ;
POP AX ;возвращаем скан-код из стека
;---проверка клавиши сдвига
CMP AL,42 ;нажат левый сдвиг?
JNE KEY_UP ;нет - смотрим следующее
MOV BL,1 ;да - изменяем бит статуса
OR ES:[17H],BL ;меняем прямо регистр статуса
JMP QUIT ;выход из процедуры
KEY_UP: CMP AL,170 ;левый сдвиг отпущен?
JNE NEXTKEY ;нет - смотрим следующее
MOV BL,11111110B ;да - меняем бит статуса
AND ES:[17H],BL ;меняем прямо регистр статуса
JMP QUIT ;выход из процедуры
NEXTKEY: ;просмотр других переключателей
;---это символьная клавиша - интерпретируем скан-код
TEST AL,10000000B ;код освобождения клавиши?
JNZ QUIT ;да - выходим из процедуры
MOV BL,ES:[17H] ;иначе берем байт статуса
TEST BL,00000011B ;клавиша сдвига нажата?
JZ CONVERT_CODE ;нет - уходим дальше
ADD AL,100 ;да - значит заглавная буква
CONVERT_CODE: MOV BX,OFFSET TABLE ;готовим таблицу
XLAT TABLE ;преобразуем скан-код в ASCII
CMP AL,0 ;возвращен 0?
JE QUIT ;если да, то на выход


;---код клавиши готов, проверяем не полон ли буфер клавиатуры
MOV BX,1AH ;смещение указателя на голову
MOV CX,ES:[BX] ;получаем его значение
MOV DI,ES:[BX]+2 ;получаем указатель хвоста
CMP CX,60 ;голова на вершине буфера?
JE HIGH_END ;да - переходим к спец. случаю
INC CX ;увеличиваем указатель головы
INC CX ;на 2
CMP CX,DI ;сравниваем с указателем хвоста
JE QUIT ;если равны, то буфер полон
JMP GO_AHEAD ;иначе вставляем символ
HIGH_END: CMP DI,30 ;проверка спец. случая
JE QUIT ;если буфер полон, то выход
;---буфер не полон - вставляем в него символ
GO_AHEAD: MOV ES:[DI],AL ;помещаем символ в позицию хвоста
CMP DI,60 ;хвост в конце буфера?
JNE NO_WRAP ;если нет, то добавляем 2
MOV DI,28 ;иначе указатель хвоста = 28+2
NO_WRAP: ADD DI,2 ;получаем новое значение хвоста
MOV ES:[BX]+2,DI ;посылаем его в область данных
;---завершение прерывания
QUIT: POP ES ;восстанавливаем изменяемые
POP DI ;регистры
POP CX ;
POP BX ;
POP AX ;
MOV AL,20H ;выдаем сигнал об окончании
OUT 20H,AL ;аппаратного прерывания
IRET ;возврат из прерывания
NEW_KEYBOARD ENDP


    Раздел 2. Доступ к отдельным клавишам.



Процедура обработки нажатия клавиши должна проверять массу
различных типов клавиш и условий, поскольку как одно-, так и
двухбайтные коды могут появляться в комбинации с клавишами-перек-
лючателями. Не все клавиши логически сгруппированы, по типу кода,
который им соответствует. Например, клавиша <Backspace> генери-
рует однобайтный код ASCII, а клавиша <Delete> - двухбайтный
расширенный код. Клавиша Ctlr генерирует однобайтный код, когда
она используется в сочетании с алфавитными клавишами и двухбайт-
ный код в остальных случаях. Эти нерегулярности вознмкают из-за
ограниченности набора ASCII: прерывание клавиатуры следует согла-
шениям ASCII, когда возможно, но когда это невозможно выдает свои
(расширенные) коды.
В данном разделе перечислены различные группы клавиш, даны их
коды и указаны встречающиеся аномалии. В большинстве случаев эта
информация доступна в менее удобном виде из таблиц кодов ASCII и
расширенных кодов, приведенных в разделе 3 этой главы. Здесь
обсуждаются также специальные свойства, приписываемые отдельным
клавишам Бейсиком, а также специальная обработка, для интерпрета-
ции отдельных клавиш (таких как забой), применяемая в прерываниях
DOS.



    3.2.1 Использование клавиш <BackSpace>, <Enter>, <Escape> и <Tab>.



Клавиши <BackSpace>, <Enter>, <Escape> и <Tab> - единственные
четыре несимвольные клавиши, которые генерируют однобайтные ко-
ды ASCII. Эти коды содержатся в наборе управляющих кодов [7.1.9],
которые занимают первые 32 кода в наборе ASCII. Эти четыре кода
могут быть получены также комбинацией буквенных клавиш с клавишей
Ctrl:

ASCII 8 BackSpace Ctrl + H
ASCII 9 Tab Ctrl + I
ASCII 13 Enter Ctrl + M
ASCII 27 Escape Ctrl + [

В [3.2.2] показано как различать нажатие одной клавиши и комбина-
цию с клавишей Ctrl. Отметим, что обратная табуляция, производи-
мая нажатием комбинации <Shift> + <Tab>, выдает расширенный код
0;15.
Некоторые из прерываний обработки ввода с клавиатуры автомати-
чески интерпретируют эти четыре специальных кода. В Бейсике функ-
ция INPUT реагирует на <Backspace>, <Tab> и <Enter>. Функция
INKEY$ не интерпретирует ни один из управляющих кодов, поскольку
у нее нет автоматического эха на экран. Всю работу должна выпол-
нять Ваша программа. Напомним, что для управления движением кур-
сора Бейсик предоставляет функцию TAB. Из прерываний BIOS и DOS,
те которые выдают эхо на терминал интерпретируют также клавиши
<BackSpace> и <Tab>. После того как эти коды интерпретируются
соответствующим образом, коды ASCII все равно появляются в AL,
после чего они могут быть включены в строку символов или игнори-
рованы, в зависимости от того, что требуется.



    3.2.2 Использование клавиш-переключателей: <Shift>, <Ctrl> и <Alt>.



Три типа клавиш-переключателей заставляют только другие клави-
ши клавиатуры генерировать различные коды. Как правило, такие
комбинации генерируют расширенные коды. Но в двух случаях они
дают коды ASCII: (1) когда используется клавиша <Shift> с
клавишами
алфавитно-цифровых символов и (2) нажатие комбинации клавиш от
Ctrl-A до Ctrl-Z дает ASCII коды от 1 до 26. Все остальные комби-
нации дают расширенные коды, перечисленные в [3.3.5]. PCjr имеет
несколько исключений, которые обсуждаются ниже.
Недопустимые комбинации клавиш не производят кода, вообще. За
исключением случая специальных комбинаций с Ctrl-Alt, одновремен-
ное нажатие нескольких переключателей приводит к тому, что только
один из них становится эффективным, причем приоритет у Alt, затем
Ctrl, и затем Shift. В [3.1.7] показано как проверить нажата ли в
данный момент клавиша-переключатель. В [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] пока-