; Библиотека работы с клавиатурой
keybLibrary

COM_A   EQU     19h
DAT_A   EQU     18h

;From z84c15 SIO instruction
;COM_A Read
;d0 - Rx Character available
;d1 - Int panding (Ch.A only)
;d2 - Tx buffer empty
;d3 - DCD
;d4 - Syan/Hunt
;d5 - CTS
;d6 - Tx Under.../ EOM
;d7 - Break/Abort
;Note: d3-d7 used with "External Status Interrupt" Modes

; Установка портов режима
; в соответствии с описанием
; последовательного порта z84c15
; use: a
keybLibInit
    ld a,#00
    out (COM_A),a
    ld a,#01
    out (COM_A),a
    ld a,#00
    out (COM_A),a
    ld a,#03
    out (COM_A),a
    ld a,#c1
    out (COM_A),a
    ld a,#04
    out (COM_A),a
    ld a,#05
    out (COM_A),a
    ld a,#05
    out (COM_A),a
    ld a,#62
    out (COM_A),a
    ret


; Считывание с клавиатуры пр прерываниям
; use: hl,de,af
keybIntHandler
    ld hl,keybBufferSize
    ld de,(_keybBufferPosWrite)
_keybIntHandlerLoop
    in a,(COM_A)
    bit 0,a         ; проверить наличие байта
    ret z           ; вернуться, если нет байта
    in a,(DAT_A)    ; считать байт
    ld (de),a
    inc e
    ld (_keybBufferPosWrite),de
    inc (hl)
    jp _keybIntHandlerLoop


; Очистка буфера
; use: hl,af
keybClearBuff
    di
    xor a
    ld (keybBufferSize),a
    ld hl,keybBuffer
    ld (keybBufferPosRead),hl
    ld (_keybBufferPosWrite),hl
_keybClearBuffLoop
    in a,(COM_A)
    bit 0,a         ; проверить наличие байта
    ret z           ; вернуться, если нет байта
    in a,(DAT_A)    ; считать байт
    jp _keybClearBuffLoop


; Читаем и декодируем данные из буфера
; use: hl,de,af
; ret:
;   a - code (0 if no data)
;   carry=1 if release =0 if presseed
keybGetKey
    ld hl,keybBufferSize
    ld de,(keybBufferPosRead)
    ld a,(hl)
    ld b,a
    or a
    ret z
    ld a,(de): inc e
    cp #f0
    jr z,keybGetKeyF0; release
    cp #e0
    jr z,keybGetKeyE0; prefix E0
    ld (keybBufferPosRead),de: dec (hl)
keybGetKeyHasKeyPressed
    and a
keybGetKeyHasKey
    ld h,#40
    ld l,a
    ld a,(hl)
    ret
keybGetKeyF0; release
    dec (hl)
    jr z,keybGetKeyNoData
    ld a,(de): inc e
    ld (keybBufferPosRead),de: dec (hl)
    scf
    jr keybGetKeyHasKey
keybGetKeyE0; prefix E0
    dec (hl)
    jr z,keybGetKeyNoData
    ld a,(de): inc e
    cp #f0
    jr z,keybGetKeyE0F0; prefix E0, release
    ld (keybBufferPosRead),de: dec (hl)
    add a,#80
    jr keybGetKeyHasKeyPressed
keybGetKeyE0F0; prefix E0,release
    dec (hl)
    jr z,keybGetKeyNoData2
    ld a,(de): inc e
    ld (keybBufferPosRead),de: dec (hl)
    add a,#80
    scf
    jr keybGetKeyHasKey
keybGetKeyNoData2
    inc (hl)
keybGetKeyNoData
    inc (hl)
    xor a
    ret

keybBufferSize db 0
keybBufferPosRead dw keybBuffer
_keybBufferPosWrite dw keybBuffer

    align 256
keybBuffer ds 256,0
