User Tag List

Страница 2 из 2 ПерваяПервая 12
Показано с 11 по 14 из 14

Тема: Процедура опроса клавиатуры

  1. #11
    Veteran
    Регистрация
    08.01.2007
    Адрес
    г. Красноярск
    Сообщений
    1,280
    Спасибо Благодарностей отдано 
    277
    Спасибо Благодарностей получено 
    1,410
    Поблагодарили
    281 сообщений
    Mentioned
    7 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Процедура попроще:

    XOR A
    LD (23560),A
    LD IY,#5C3A
    RST 56

    Вешается на прерывания. Последнюю нажатую клавишу можно получить из ячейки по адресу 23560.

    По адресам 23561 и 23562 можно изменить задержку опроса клавиш.

    Автор процедуры Fyrex/Mayhem.

  2. #12
    DimkaM
    Гость

    По умолчанию

    Немного не то. Нужна с буфером.

  3. #13
    Veteran Аватар для Oleg N. Cher
    Регистрация
    24.08.2007
    Адрес
    Днепропетровская обл.
    Сообщений
    1,643
    Спасибо Благодарностей отдано 
    2,246
    Спасибо Благодарностей получено 
    147
    Поблагодарили
    112 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    Цитата Сообщение от DimkaM Посмотреть сообщение
    Нужна процедура опроса клавиатуры, желательно наиболее полная, висящая на прерывании, а если будет с буфером, то вообще супер.
    Буферизованный опрос клавиатуры, реализованный для ZXDev. Коды клавиш берутся из LAST_K, соответственно, работает автоповтор клавиш. Исходник оформлен для сборки компилятором SDCC.

    Код:
    #define KeyBufSize 8
    
    // Возвращает количество клавиш в буфере.
    unsigned char Input_Available (void);
    
    // Возвращает код нажатой клавиши.
    // Если нажатых клавиш нет, ожидает.
    char Input_Read (void);
    
    // Вызывайте из обработчика прерываний IM 2.
    void Input_RunMe50Hz (void);
    
    /*--------------------------------- Cut here ---------------------------------*/
    char Input_keyBuf [KeyBufSize];
    
    /* Закономерно считаем, что более актуальны клавиши, нажатые позднее,
       поэтому при переполнении буфера будем удалять из него нажатые ранее.
       Эта стратегия кажется более удачной, чем игнорирование всех клавиш,
       нажатых после переполнения буфера (как в контроллере клавиатуры IBM PC). */
    
    char Input_Read (void) {
    __asm
    LOOPrptbuf$:
      LD   HL,#_Input_keysAvailable+1
      LD   A,(HL)
      OR   A
      JR   Z,LOOPrptbuf$
      DEC  (HL)
    .globl _Input_keyOut
    _Input_keyOut:           ; Read a key:
      LD   HL,#_Input_keyBuf ; key := keyBuf[keyOut];
      LD   C,(HL)
      INC  HL                ; keyOut := (keyOut+1) MOD KeyBufSize;
      LD   A,L
      SUB  #<_Input_keyBuf+KeyBufSize
      JR   NZ,Save_keyOut$
      LD   HL,#_Input_keyBuf
    Save_keyOut$:
      LD   (_Input_keyOut+1),HL
      LD   L,C               ; RETURN key
    __endasm;
    } //Input_Read
    
    void Input_RunMe50Hz (void) __naked {
    __asm
      LD   IY,#0x5C3A
      RST  0x38
      BIT  5,1(IY)
      RET  Z
      RES  5,1(IY)
    _Input_keyIn:
      LD   HL,#_Input_keyBuf ; Add a key:
      LD   A,-50(IY)         ; keyBuf[keyIn] := CHR(keyCode);
      LD   (HL),A
      INC  HL
      LD   A,L
      SUB  #<_Input_keyBuf+KeyBufSize
      JR   NZ,Save_keyIn$
      LD   HL,#_Input_keyBuf
    Save_keyIn$:
      LD   (_Input_keyIn+1),HL
    .globl _Input_keysAvailable
    _Input_keysAvailable:
      LD   A,#0              ; Check overflow:
      CP   #8                ; IF keysAvailable > 8 THEN keysAvailable := 8 END;
      ADC  #0
      LD   (_Input_keysAvailable+1),A
      RET  C
      JR   _Input_keyOut
    __endasm;
    } //Input_RunMe50Hz
    
    /*--------------------------------- Cut here ---------------------------------*/
    unsigned char Input_Available (void) {
    __asm
      LD   HL,(_Input_keysAvailable+1)
    __endasm;
    } //Input_Available
    Вопросы, предложения, критика?

  4. #14
    Veteran Аватар для Oleg N. Cher
    Регистрация
    24.08.2007
    Адрес
    Днепропетровская обл.
    Сообщений
    1,643
    Спасибо Благодарностей отдано 
    2,246
    Спасибо Благодарностей получено 
    147
    Поблагодарили
    112 сообщений
    Mentioned
    1 Post(s)
    Tagged
    0 Thread(s)

    По умолчанию

    В приведённом выше коде есть баг (!). Было:
    Код:
    .globl _Input_keysAvailable
    _Input_keysAvailable:
      LD   A,#0              ; Check overflow:
      CP   #8                ; IF keysAvailable > 8 THEN keysAvailable := 8 END;
      ADC  #0
      LD   (_Input_keysAvailable+1),A
      RET  C
      JR   _Input_keyOut
    Стало:
    Код:
    .globl _Input_keysAvailable
    _Input_keysAvailable:
      LD   A,#0              ; Check overflow:
      CP   #KeyBufSize       ; IF keysAvailable > 8 THEN keysAvailable := 8 END;
      JR   NC,_Input_keyOut
      INC  A
      LD   (_Input_keysAvailable+1),A
      RET
    Баг связан с тем, что не было учтено влияние команды ADC #0 на флаг переноса, и процедура реагировала без переполнения буфера как на его переполнение.
    Последний раз редактировалось Oleg N. Cher; 25.12.2014 в 15:58.

Страница 2 из 2 ПерваяПервая 12

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Похожие темы

  1. процедура загрузки с диска
    от necroTrue в разделе Программирование
    Ответов: 18
    Последнее: 18.08.2011, 17:18
  2. нужна процедура умножения 16b*8b
    от DimkaM в разделе Программирование
    Ответов: 0
    Последнее: 16.04.2010, 10:29
  3. Глюк опроса клавиатуры
    от POIND в разделе Устройства ввода
    Ответов: 15
    Последнее: 20.06.2005, 16:03
  4. Процедура детекта TurboSound.
    от Shiru в разделе Программирование
    Ответов: 21
    Последнее: 27.05.2005, 18:45
  5. Процедура опроса клавиатуры
    от Aprisobal в разделе Программирование
    Ответов: 8
    Последнее: 19.02.2005, 18:12

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •