Login

Subversion Repositories NedoOS

Rev

Rev 565 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

;кодировка 866!
;notepad++ неправильно определяет кодировку
;поэтому напишем здесь довольно много текста кириллицей
;поэтому напишем здесь довольно много текста кириллицей
;поэтому напишем здесь довольно много текста кириллицей
numlangs=3 ;including graph

keyqueuemax=2;5

kZ=0 ;ja w e r t y
kJ=0 ;j c u k e n
multikbd=0
kR=1 ;sh w e r t y
NkJ=kZ+kR
ukr=1

KEYM0change
        LD (keym0BC),BC
        LD (keym0HL),HL
        ld c,d ;C=very old state
        LD D,A ;D=changes
        LD B,5 ;5 keys in a halfrow
KEYM1   RR D
        jr NC,KEYMnPUT
        LD (keym1BC),BC
        LD (keym1DE),DE
keymshifts=$+1
        LD D,0
;C0=press(1)/release(0)
;E=scancode, D=shiftstate
;D=%00: ext
;D=%01: cs
;D=%10: ss
;D=%11: no shifts
        DEC D
        LD HL,tkeydecodecs
        jr Z,KEYDECODEPASS ;cs+key
        DEC D
        LD HL,tkeydecodess
        JR z,KEYDECODEPASS ;ss+key
        DEC D
        LD HL,tkeydecode
        jr Z,KEYDECODEPASS ;no shifts+key
        LD HL,tkeydecodeext ;ext+key
KEYDECODEPASS
        LD D,0
        ADD HL,DE
        ld A,(HL)
       CP ssnoshifts ;crucial for autorepeat of ssSpace
       jr Z,KEYMPUTSKIP
       CP csnoshifts ;csnoshifts keypress can appear in the same frame as cs6 etc and must be ignored
keym_keyrep
       LD B,E
        CALL NZ,KEYREP ;A=code
                       ;C0=press(1)/release(0)
                       ;B=scancode without shifts
KEYMPUTSKIP
keym1DE=$+1
        LD DE,0
keym1BC=$+1
        LD BC,0
KEYMnPUT
        INC E
        RR C
        DJNZ KEYM1
keym0HL=$+1
        LD HL,0
keym0BC=$+1
        LD BC,0
        jp KEYM0nexthalfrow

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
KEYSCAN
;to make shifts always press no later than alphanumerics
;use old scanchange of alphanumerics and old&new scan of shifts (to make them longer)
;tkeymatrixstate (even) = old scan
;tkeymatrixstate+1 (odd) = very old scan

KEYMATRIX
        LD HL,tkeymatrixstate +(2*7)
        LD BC,0x7FFE
         ld a,c
         in a,(0xfe) ;cs halfrow
         and (hl) ;old cs halfrow
         ld e,a
        LD HL,tkeymatrixstate
        IN A,(C) ;ss halfrow
         and (hl) ;old ss halfrow
        RRA
        RRA ;ss
        ;LD A,C
        ;IN A,(0xFE)
         ld a,e
        RLA
        AND 3
        LD (keymshifts),A ;A0=ss,A1=cs
        LD E,0 ;scancode ;Space=0, cs=35
KEYM0   ;IN A,(C)
         ld a,(hl) ;old state (to use)
         ini ;current keymatrix for alphanumerics will be used in the next frame
         inc b
         ;inc hl
        LD d,(HL) ;very old state
        ld (HL),A ;old state (to use)
        XOR d ;very old state
         jr nz,KEYM0change
        ld a,e
        add a,5
        ld e,a
KEYM0nexthalfrow
        INC HL
        RRC B ;next halfrow
        jp C,KEYM0

        if 1==0
;current keymatrix for alphanumerics will be used in the next frame
        ld hl,tkeymatrixstate
        LD BC,0x7FFE ;Space=0, cs=35
KEYSCAN0
        IN A,(C)
        ld (hl),a
        inc hl
        ;ini
        ;inc b
        inc hl
        rrc b
        jp c,KEYSCAN0
        endif
       
;blowing
        ld a,(keyrepcounter)
        OR A
        RET Z
        DEC A
        jr Z,KEYREPSEND
KEYREPSETCNT
        LD (keyrepcounter),A
        RET

;C0=press(1)/release(0)
;A=code
;B=scancode without shifts
KEYREP
        IF 1==0
        push af
        push bc
        push de
        push hl
        ld a,b
        add a,'A'      
        ld c,a
        ld b,0
        call KEYQUEUEPUT
        ld a,(keyrepscancode)
        add a,'A'
        ld c,a
        ld b,0
        call KEYQUEUEPUT
        pop hl
        pop de
        pop bc
        pop af
        ENDIF
        RR C ;NC=release
        jr C,KEYREPPRESS
;CP/M: if this is "ext" (cs or ext release): if keyrepkey was "ext", then make "ext" keypress (and forget "ext" to avoid "ext, cs" work as ext, ext), else make "csnoshifts" keypress (for AltGr)
         cp csss
         jr nz,KEYREPRELEASE
keyrepkey=$+1
        cp 0
        ld a,csnoshifts
        LD (keyrepkey),A ;forget "ext" to avoid "ext, cs" work as ext, ext
        jr nz,KEYREPSEND
        ld a,csss
        jr KEYREPSENDA
KEYREPRELEASE
;if the repeated key (without shifts) is released
;then stop key repeat
;or else ignore
       LD A,B ;scancode without shifts
keyrepscancode=$+1
       SUB -1
        RET NZ
      ;XOR A
       JR KEYREPSETCNT
KEYREPPRESS
        cp cssspress ;=csss
        jr nz,KEYREPPRESSncsss
keyrepcounter=$+1
        LD d,0
        inc d
        dec d
        ret nz ;ext keypress, but another key is already pressed - ignore ext ;to filter out ext keypress in the same frame as ext+3 keypress (ss+PgUp pressed)
        ;z
KEYREPPRESSncsss
       LD (keyrepkey),A
        ret z ;no "ext" keypress, only release
       SUB cs1;'1'-32
       CP 2
       jr C,KEYREPSEND ;no autorep for cs1..2
       LD A,B ;scancode without shifts
       LD (keyrepscancode),A
        LD A,14;10
        LD (keyrepcounter),A
KEYREPSEND
         ld a,(keyrepkey)
KEYREPSENDA
         
;A = code ;[(cs+1 was encoded as '1'-32)]
;csnoshifts means CS release
;idle: cs1..2 start, csnoshifts skip, others pass by
;working: cs0..9 add, others end (1,2 add cs0)
KEYALTGR
altgrN=$+1
        LD BC,0x100 ;C=AltGr code (0=idle), B=1 (codes)
         ld e,a ;current key
           sub cs0;'0'-32
           jr z,KEYALTGRcs0
        SUB cs1-1 -cs0
KEYALTGRcs0
       LD D,A ;0..9 in good case
       INC C
       DEC C
       jr Z,KEYALTGR_IDLE
        CP 10
       LD A,C
        jr NC,KEYALTGRPUT ;stop AltGr (csnoshifts or wrong key) ;a=final code
        ADD A,A
        ADD A,A
        ADD A,C
        ADD A,A ;D*10
        ADD A,D
KEYALTGRN
        LD (altgrN),A
        RET
KEYALTGR_IDLE
;A=1..2 in good case
        DEC A
        CP 2 ;CY=1: cs1/cs2
        INC A
        jr C,KEYALTGRN ;start AltGr
         ld a,e ;current key
        jr KEYALTGRPUT_NO1_2 ;for passing extA(=1),extB(=2)
KEYALTGRPUT
;cs release gives final code here (=1 or 2 for single keypress of cs1 or cs2)
        cp 3
        jr nc,$+5
            add a,cs1-1
KEYALTGRPUT_NO1_2
            inc b ;control keys
        or a;CP csnoshifts
        RET Z ;avoid NOKEY
        LD C,A
       XOR A
       LD (altgrN),A ;idle

;BC=code (B=2 => might be control code) (B=1 means AltGr symbol, for KEYLANG passby)
KEYSWITCH
       DEC B
       jr Z,KEYSWPASS ;B=0 ;AltGr symbol, for KEYLANG passby
        LD A,C
        ;push af
        ;push bc
        ;ld bc,'a'
        ;ld c,a
        ;call KEYQUEUEPUT
        ;pop bc
        ;pop af
keyswstate=$+1
        LD HL,0x100 ;H=язык=1..numlangs (H=numlangs при graph)
                   ;L0=CapsLock
        CP cs2
        jr Z,KEYSWCAPSLOCK
        CP cs1
        jr Z,KEYSWLANG
        CP graphlock;ext1
        jr NZ,KEYSWPASS
KEYSWGRAPH
        LD A,H
        LD H,numlangs
        CP H ;graph уже включен?
        jr NZ,KEYSWOK ;нет - включаем, иначе DEC H
KEYSWLANG
        DEC H
        jr NZ,$+4
        LD H,numlangs-1
        DEC L
KEYSWCAPSLOCK
        INC L
KEYSWOK
        LD (keyswstate),HL
;pass key to make possible to redraw blinking cursor
KEYSWPASS

;BC=code (B=0 means AltGr symbol, for KEYLANG passby) (B=1 for usual keys)
KEYLANG
        INC B
        DEC B
        jr Z,KEYLANGPASS ;B=0: symbol from ALTGR
;B=1
        ;CALL KEYQUEUEPUT ;BC=code
        ld (keyqueueput_codenolang),bc
KEYLANG_REPEAT
        LD A,C
        LD (keylangcode),A
         ;sub graphlock;ext1 ;how it worked in ACEdit without this check?
         ;jr z,KEYLANGPASS_A ;B=1 (control key) ;a=0=NOKEY => c
         ;sub cs1-graphlock;ext1 ;how it worked in ACEdit without this check?
         ;jr z,KEYLANGPASS_A ;B=1 (control key) ;a=0=NOKEY => c
         ;sub cs2-cs1 ;how it worked in ACEdit without this check?
         ;jr z,KEYLANGPASS_A ;B=1 (control key) ;a=0=NOKEY => c
         ;SUB 0xff&(32-cs2)
         cp graphlock;ext1 ;how it worked in ACEdit without this check?
         ret z
         cp cs1 ;how it worked in ACEdit without this check?
         ret z
         cp cs2 ;how it worked in ACEdit without this check?
         ret z
         SUB ' '
        CP 95
        jr NC,KEYLANGPASS ;B=1 (control key)
rustrdisp=$+1
       LD DE,0 ;D=0
       INC E
       DEC E
       jr NZ,KEYLANG_SHV2 ;second key of combination?
keylangcode=$+1
        LD BC,0 ;B=0, C=code
        LD DE,(keyswstate)
;BC=code
        DEC D
        jr Z,KEYL_ENG ;B=0
        DEC D
        jr NZ,KEYL_GRAPH ;B=0
KEYL_RUSTR
;B=0
       IF multikbd
kmode=$+1
        LD A,1
        CP kR
        jr Z,KEYL_SHVERTY
        CALL RERUS
        JR KEYLANGPUT ;B=0
KEYL_SHVERTY
       ENDIF
        LD A,C
        CP 64
        jr C,KEYLANGPUT ;B=0
        LD HL,tkeyl_rustr
        ADD HL,BC
        LD C,(HL)
        LD A,C
        CP 64
        jr NC,KEYLANGPUT ;B=0
       ;LD (rustrdisp),BC ;B=0
      ;LD A,C
       LD (rustrdisp),A
        ;RET
        ld c,b ;b=0 ;put keylang=0 with current keynolang
        jr KEYLANGQ
       
KEYLANG_SHV2
        LD (rustrNEW),BC
       LD A,C;(rustrNEW)
      ;LD (rustrNEW),A
;rustrdisp=$+1
       ;LD DE,0 ;D=0
        LD HL,tkeyl_rustrc
        ADD HL,DE
        LD C,(HL) ;len
       LD B,D ;=0
        INC HL
        LD E,C
        CPIR
        LD C,E ;B=0
        ADD HL,BC
        jr Z,KEYLANGCOMBO ;combination entered (such as qq)
;no such combination - take symbol #len
       LD A,(HL)
       CALL case
       LD C,A
        CALL KEYQUEUEPUT ;B=0
rustrNEW=$+1
       LD BC,0 ;B=0
       XOR A
       LD (rustrdisp),A
         ld h,a
         ld l,a
         ;ld (keyqueueput_codenolang),hl ;no keynolang for 2nd symbol
        JR KEYLANG_REPEAT ;doubling and recoding the 2nd symbol
KEYL_GRAPH
;B=0
;'0' -> 0030
;'1' -> 0031
;'2' -> 0032
;'3' -> 0033
;'4' -> 0034
;'a' -> 0061
;do "case" first!!!
       LD A,C
       CALL case
       LD C,A
        LD HL,tkeyl_graph
        ADD HL,BC
        LD C,(HL)
        jr KEYLANGPASS
       
KEYLANGCOMBO
        DEC HL
        LD C,(HL)
KEYL_ENG ;B=0
KEYLANGPUT ;B=0
       LD A,C
       CALL case
;KEYLANGPASS_A ;A=0
       LD C,A
KEYLANGPASS
       XOR A
       LD (rustrdisp),A
KEYLANGQ
        jp KEYQUEUEPUT

tkeydecodeext
        DB key_extspace,ssnoshifts,extM,extN,extB
        DB extenter,extL,extK,extJ,extH
        DB extP,extO,extI,extU,extY
        DB ext0,ext9,ext8,ext7,ext6
        DB ext1,ext2,ext3,ext4,ext5
        DB extQ,extW,extE,extR,extT
        DB extA,extS,extD,extF,extG
        DB cssspress,extZ,extX,extC,extV
tkeydecode
        DB " ",ssnoshifts,"mnb"
        DB key_enter,"lkjh"
        DB "poiuy"
        DB "09876"
        DB "12345"
        DB "qwert"
        DB "asdfg"
        DB csss,"zxcv"
tkeydecodecs
        DB key_esc,ssnoshifts,"MNB"
        DB key_csenter,"LKJH"
        DB "POIUY"
        ;DB '0'-32,'9'-32,'8'-32,'7'-32,'6'-32
        ;DB '1'-32,'2'-32,'3'-32,'4'-32,'5'-32
        db cs0,cs9,cs8,cs7,cs6
        db cs1,cs2,cs3,cs4,cs5
        DB "QWERT"
        DB "ASDFG"
        DB csnoshifts,"ZXCV"
tkeydecodess
        DB key_ssspace,ssnoshifts,".,*"
        DB ssnoshifts,"=+-^"
        DB 34,";",ssI,"]["
        DB "_)('&"
        DB "!@#$%"
        DB ssQ,ssW,ssE,"<>"
        DB "~|",0x5c,"{}"
        DB csss,":`?/" ;in fact csss keypress is taken from tkeydecodeext, csss release from tkeydecodecs
tkeymatrixstate
        ;DS 8,0xFF ;initially nothing pressed
        DS 16,0xFF ;initially nothing pressed

tkeyl_graph=$-32
        DB 32,14,34,16,17,18,19,20,"()*+,-./"
        DB 12,1,2,3,4,5,6,7,8,11,":;єўЄ?"
        DB 15,"╠╧╝╣╗╞╪╡▄▀■¤№╛▌▐╔╒╬╤█╘╦╩╕╚[",0x5c,"]^_"
        DB "`├╨┘┤┐╟╫╢─░▒▓√╜║═┌╓┼╥│╙┬┴╖└{|}~"
tkeyl_rustr=$-64
        DB "@АБ",rustrCdisp
        DB "ДЕФГ",rustrHdisp,"И",rustrJdisp
        DB "КЛМНОП",rustrQdisp
        DB "РСТУЖВЬЫЗ[",0x5c,"]^_"
        DB "`аб",rustrcdisp
        DB "дефг",rustrhdisp,"и",rustrjdisp
        DB "клмноп",rustrqdisp
        DB "рстужвьыз{|}~"

tkeyl_rustrc=$-1 ;to avoid zero displacements
rustrhdisp=$-tkeyl_rustrc
        DB 1,"h","э","х"
rustrHdisp=$-tkeyl_rustrc
        DB 1,"H","Э","Х"
rustrqdisp=$-tkeyl_rustrc
        DB 1,"q","щ","ш"
rustrQdisp=$-tkeyl_rustrc
        DB 1,"Q","Щ","Ш"
rustrcdisp=$-tkeyl_rustrc
       IF ukr
        DB 2,"gc",0xF3,"ц","ч"
       ELSE
        DB 1,"c","ц","ч"
       ENDIF
rustrCdisp=$-tkeyl_rustrc
       IF ukr
        DB 2,"GC",0xF2,"Ц","Ч"
       ELSE
        DB 1,"C","Ц","Ч"
       ENDIF
rustrjdisp=$-tkeyl_rustrc
       IF ukr
        DB 7,"eyiaouj",0xF5,0xF7,0xF9,"яёюъ","й"
       ELSE
        DB 4,"aouj","яёюъ","й"
       ENDIF
rustrJdisp=$-tkeyl_rustrc
        DISPLAY $-tkeyl_rustrc,"<64"
       IF ukr
        DB 7,"EYIAOUJ",0xF4,0xF6,0xF8,"ЯЁЮЪ","Й"
       ELSE
        DB 4,"AOUJ","ЯЁЮЪ","Й"
       ENDIF

       IF kZ
rt
        DB "ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧъ"
       ENDIF
       IF kJ
rtjcuk
        DB "@ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ[",0x5c,"]^_"
       ENDIF
RERUS
;in: C=code (32..126), A=kmode
;out: C=code
;keeps B
        LD D,C ;code
       IF kZ
        LD HL,rt
       ENDIF
       IF kJ
        IF multikbd
        CP NkJ
        jr NZ,rERUSnJCUK
        ENDIF
        LD HL,rtjcuk
        LD A,D ;code
        LD C,'б'
        CP '!'
        RET Z
        LD C,'ж'
        CP '@'
        RET Z
        LD C,'х'
        SUB '#'
        RET Z
        LD C,'э'
        DEC A ;'$'
        RET Z
        INC C ;'ю'
        DEC A ;'%'
        RET Z
rERUSnJCUK ;
       ENDIF
        LD A,D ;code (32..126)
        LD C,'ё'
        CP '&'
        RET Z
        LD C,D
        BIT 6,D ;code
        RET Z ;code <64 (not letter) - return old code
;A=code (64..126)
        AND 31
        ADD A,L
        LD L,A
        jr NC,$+3
        INC H
        LD A,(HL) ;capital Russian
        BIT 7,A
        RET Z ;not a letter in the table - return old code
        LD C,A ;capital Russian
        BIT 5,D ;code
        RET Z ;C contained capital letter, return capital
        CALL RECAP
        LD C,A ;small Russian
        RET

CHECKCAPSLOCK
        PUSH HL
        LD HL,keyswstate
        BIT 0,(HL)
        POP HL
        RET
case
        CALL CHECKCAPSLOCK
        RET Z
RECAP
        CP 0xf2;je'Є'
        RET NC
        XOR 1
        CP 0xf0;jo'Ё'
        RET NC
        XOR 1
        CP 0xe0;'р'
        jr NC,BECAPRL
        CP 0xb0;'-'
        RET NC
        CP 0xa0;'а'
        jr NC,BECAPOK
        CP 0x90;'Р'
        jr NC,BECAPRL
        CP 0x80;'А'
        jr NC,BECAPOK
        CP '@'
        RET Z
        CP '_'
        RET Z
        CP 'A'
        RET C
        CP '{'
        RET NC
        CP '['
        jr C,$+5
        CP 'a'
        RET C
BECAPOK XOR 80
BECAPRL XOR 0x70
        RET