EKEY

Материал из ПМК вики
Перейти к навигации Перейти к поиску

EKEY (и-клавиша) — стандартное слово Каллисто. Ожидание нажатия клавиши.

EKEY           ( −− c )                             Ожидание нажатия клавиши и получение её кода.

Слово EKEY ожидает нажатия клавиши на клавиатуре, после нажатия кладёт её код (число от 0 до 37) на стек. Обращения к индикатору не происходит, курсор не выводится.

Чтобы узнать, какая клавиша нажата, не останавливая приложение, используйте слово INKEY. Для ввода не клавиши, а литеры служит слово KEY.

Ввод слова EKEY[править]

В режиме ЛАТ последовательно нажмите четыре клавиши  ИП   9   ИП    ,  

EKEY в стандарте ANS Forth[править]

 10.6.2.1305   EKEY                            "e-key"              FACILITY EXT
            ( -- u )
            Получает одно событие клавиатуры u. Кодирование событий клавиатуры 
            определенное реализацией.

        См.: 10.6.1.1755 KEY?, 6.1.1750 KEY.

 A.10.6.2.1305   EKEY
 EKEY предоставляет стандартное слово для обращения к зависимому от системы 
 набору "необработанных" событий клавиатуры, включая события соответствующие 
 членам стандартного набора символов, события соответствующие другим членам 
 определенного реализацией набора символов, и нажатия клавиш которые не 
 соответствуют членам набора символов.

 EKEY не предполагает никакого специфического числового соответствия между 
 специфическими значениями кода события и значениями, представляющими 
 стандартные символы. На некоторых системах, оно может допускать две отдельные 
 клавиши, которые соответствуют одному и тому же стандартному символу, которые 
 нужно отличить друг от друга.

 В системах, которые объединяют события клавиатуры и мыши в один "поток 
 событий", единственное число, возвращенное EKEY, может быть неадекватно для 
 представления полного диапазона возможного ввода. В таких системах, отдельная 
 "запись события" может включать временную отметку, x,y координаты позиции мыши, 
 состояния клавиатуры, и состояния кнопок мыши. В таких системах могло бы быть 
 соответствующее EKEY для возвращения адреса "записи события" из которой могла 
 быть извлечена другая информация.

 Также рассмотрите гипотетическую систему Forth, выполняющуюся под MS-DOS на PC 
 совместимом компьютере. Предположите, что набор символов определенный 
 реализацией - "нормальный" PC 8-бит набор символов. В этом наборе символов коды 
 от 0 до 127 соответствуют ASCII символам. Коды от 128 до 255 представляют 
 символы из различных не английских языков, математические символы, и некоторые 
 графические символы, используемые для рисования в строке. В добавление к этим 
 символам, клавиатура может генерировать различные другие "скэн-коды", 
 представляющие такие не символьные события как клавиши курсора и функциональные 
 клавиши.

 Могут быть составные клавиши, с различными скэн-кодами, соответствующими одному 
 и тому же стандартному символу. Например, символ представляющий число "1" часто 
 появляется в строке цифровых клавиш выше алфавитных клавиш, и также в отдельной 
 цифровой клавиатуре.

 Когда программа опрашивает операционную систему MS-DOS для события клавиатуры, 
 она получает единственный ненулевой байт представляющий символ, или нулевой 
 байт, сопровождаемый байтом "скэн-кода", представляющим не символьное событие 
 клавиатуры (например, функциональная клавиша).

 EKEY представляет каждое событие клавиатуры скорее как отдельное число, чем как 
 последовательность чисел. Для системы описанной выше, следующее было бы 
 разумной реализацией EKEY и связанных слов:

 Запрос к окружению MAX-CHAR возвратил бы 255.

 Предположите существование слова DOS-KEY ( -- char ) которое выполняет 
 системный вызов MS-DOS "Прямой Ввод STDIN" (Прерывание 21h, Функция 07h) и 
 слово DOS-KEY? ( -- flag) которое выполняет системный вызов MS-DOS "Проверка 
 Состояния STDIN" (Прерывание 21h, Функция 0Bh).

        : EKEY?  ( -- flag )  DOS-KEY?  0<>  ;

        : EKEY  ( -- u )  DOS-KEY  ?DUP 0= IF  DOS-KEY 256 +  THEN ;

        : EKEY>CHAR  ( u -- u false | char true )
           DUP 255 > IF          ( u )
             DUP 259 = IF         \ 259 это Ctrl-@ (ASCII NUL)
               DROP 0 TRUE EXIT   \ если так - замена символом
             THEN FALSE EXIT      \ иначе расширенный символ
           THEN  TRUE             \ нормальный символ ASCII.
        ;

        VARIABLE PENDING-CHAR   -1 PENDING-CHAR !

        : KEY?  ( -- flag )
           PENDING-CHAR @ 0< IF
              BEGIN  EKEY? WHILE
                EKEY EKEY>CHAR IF
                  PENDING-CHAR !  TRUE EXIT
                THEN DROP
              REPEAT  FALSE EXIT
           THEN  TRUE
        ;

        : KEY  ( -- char )
           PENDING-CHAR @ 0< IF
              BEGIN  EKEY  EKEY>CHAR 0= WHILE
                DROP
              REPEAT  EXIT
           THEN  PENDING-CHAR @  -1 PENDING-CHAR !
        ;

 Это - полнофункциональная реализация, предоставляющая прикладной программе 
 простой путь, или обрабатывать не символьные события (с помощью EKEY), или 
 игнорировать их и только рассматривать "реальные" символы (с помощью KEY).

 Заметьте, что EKEY отображает скэн-коды от 0 до 255 в числа от 256 до 511. EKEY 
 отображает число 259, представляя комбинацию клавиатуры Ctrl-Shift-@ в символ, 
 чье числовое значение - 0 (ASCII NUL). Много ASCII клавиатур генерируют ASCII 
 NUL для Ctrl-Shift-@, так что мы используем эту комбинацию клавиш для ASCII NUL 
 (который иначе недоступен из MS-DOS, потому что нулевой байт показывает, что 
 следует другой байт скэн-кода).

 Одно следствие использования системного вызова "Прямого Ввода STDIN" (функция 
 7) вместо системного вызова "Ввода STDIN" (функция 8) - это что нормальное 
 поведение DOS "прерывания Ctrl-C" - заблокировано, когда система ожидает ввода 
 (Ctrl-C все еще вызвало бы прерывание, пока символы выводятся). С другой 
 стороны, если системный вызов "Ввод STDIN" (функция 8) использовался для 
 реализации EKEY, Ctrl-C прерывание было бы доступно, но Ctrl-Shift-@ также 
 вызвало бы прерывание, потому что операционная система обработает второй байт 
 из 0,3 последовательности как Ctrl-C даже притом, что эти 3 - действительно 
 скэн-код, а не символ. Одно решение "лучшее из обоих миров" - это использовать 
 функцию 8 для первого байта получаемого EKEY, и функцию 7 для байта скэн-кода. 
 Например:

        : EKEY  ( -- u )
           DOS-KEY-FUNCTION-8  ?DUP  0=  IF
             DOS-KEY-FUNCTION-7  DUP 3  =  IF
               DROP 0  ELSE  256 +
             THEN
           THEN
        ;

 Конечно, если разработчик Forth выбирает передачу Ctrl-C через программу, без 
 использования ее обычной функции обработки прерывания, тогда функция 7 DOS 
 соответствует обоим случаям (и некоторая дополнительная забота должна быть 
 предпринята для предотвращения опережающего ввода с клавиатуры Ctrl-C от 
 прерывания системы Forth в течение операций вывода).

 Система Forth могла бы также выбирать более простую реализацию KEY, без 
 реализации EKEY, следующим образом:

        : KEY   ( -- char )  DOS-KEY  ;

        : KEY?  ( -- flag )  DOS-KEY? 0<>  ;

 Недостатки более простой версии:

 a) Прикладная программа, которая использует KEY, ожидая получения только 
 допустимых символов, могла бы получить последовательность байт (например, 
 нулевой байт, сопровождаемый байтом с таким же числовым значением как у символа 
 "A") которая, кажется, содержит допустимый символ, даже притом, что 
 пользователь нажал клавишу (например, функциональная клавиша 4) которая не 
 соответствует никакому допустимому символу.

 b) Прикладная программа, которая желает обработать не символьные события, будет 
 должна выполнить KEY дважды, если она возвращает нуль первый раз. Это, могло бы 
 казалось, быть разумной и простой для воплощения вещью. Однако, такой код - не 
 переносимый на другие системы, которые не используют нулевой байт как "escape" 
 код.

 Используя подход EKEY, алгоритм для обработки событий клавиатуры может быть 
 один и тот же для всех систем; системные зависимости могут быть уменьшены до 
 таблицы или набора списка констант системно зависимых кодов клавиш используемых 
 для доступа к специфическим прикладным функциям. Без EKEY алгоритм, не только 
 таблица, вероятно будет системно зависимым.

 Другой подход к EKEY на MS-DOS состоит в том, чтобы использовать функцию BIOS 
 "Read Keyboard Status" (Прерывание 16h, Функция 01h) или связанную функцию 
 "Check Keyboard" (Прерывание 16h, Функция 11h). Преимущество этой функции 
 состоит в том, что она позволяет программе делать различие между различными 
 клавишами, которые соответствуют одному и тому же символу (например, две 
 клавиши "1"). Недостаток - то, что функция клавиатуры BIOS доступна только для 
 чтения клавиатуры. Она не может быть "переадресована" к другому источнику 
 "стандартного ввода", как может функция DOS Ввод STDIN.

Реализация[править]

1187 ;#EKEY
1188 ; EKEY             ( −− c )                             Подождать нажатия клавиши и получить её код.
1189 LEKEY:          .DB     4
1190                 .TEXT   "EKEY"
1191                 .DW     LKEY
1192 EKEY:           .DW     JEKEY
1193 JEKEY:          KM3                             ; Чтение клавиатуры МК−161 −− клавиш, а не литер.
1194 EKEYL:          PPRM 9029
1195                 PKM03
1196                 KNOT  FX!=0 EKEYL
1197                 KGOTO9

Ссылки[править]


  Nopictures-icon.png У этой статьи нет иллюстраций. Вы можете помочь проекту, добавив их.


  Stub-icon-48px.png Это заготовка статьи. Вы можете помочь проекту, дополнив её.