Subversion Repositories NedoOS

Rev

Rev 61 | Rev 147 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1. numlangs=3 ;включая graph
  2.  
  3. keyqueuemax=5
  4.  
  5. kZ=0 ;яверты
  6. kJ=0 ;йцукен
  7. multikbd=0
  8. kR=1 ;шверты
  9. NkJ=kZ+kR
  10. ukr=1
  11.  
  12. KEYSCAN
  13. KEYMATRIX
  14.         LD HL,tkeymatrixstate
  15.         LD BC,#7FFE ;Space=0, cs=35
  16.         IN A,(C)
  17.         RRA
  18.         RRA ;ss
  19.         LD A,C
  20.         IN A,(#FE)
  21.         RLA
  22.         AND 3
  23.         LD (keymshifts),A ;A0=ss,A1=cs
  24.         LD E,0 ;scancode
  25. KEYM0   IN A,(C)
  26.         LD (keym0BC),BC
  27.         LD (keym0HL),HL
  28.         LD C,(HL),(HL),A
  29.         XOR C ;C=old state
  30.         LD D,A ;D=changes
  31.         LD B,5
  32. KEYM1   RR D
  33.         jr NC,KEYMnPUT
  34.         LD (keym1BC),BC
  35.         LD (keym1DE),DE
  36. keymshifts=$+1
  37.         LD D,0
  38. ;C0=press(1)/release(0)
  39. ;E=scancode, D=shiftstate
  40. ;D=%00: ext
  41. ;D=%01: cs
  42. ;D=%10: ss
  43. ;D=%11: no shifts
  44.         DEC D
  45.         LD HL,tkeydecodecs
  46.         jr Z,KEYDECODEPASS ;cs+key
  47.         DEC D
  48.         LD HL,tkeydecodess
  49.         JR z,KEYDECODEPASS ;ss+key
  50.         DEC D
  51.         LD HL,tkeydecode
  52.         jr Z,KEYDECODEPASS ;no shifts+key
  53.         LD HL,tkeydecodeext ;ext+key
  54. KEYDECODEPASS
  55.         LD D,0
  56.         ADD HL,DE
  57.         ld A,(HL)
  58.        CP ssnoshifts ;crucial for autorepeat of ssSpace
  59.        jr Z,KEYMPUTSKIP
  60.        CP csnoshifts ;csnoshifts keypress can appear in the same frame as cs6 etc and must be ignored
  61. keym_keyrep
  62.        LD B,E
  63.         CALL NZ,KEYREP ;A=code
  64.                        ;C0=press(1)/release(0)
  65.                        ;B=scancode without shifts
  66. KEYMPUTSKIP
  67. keym1DE=$+1
  68.         LD DE,0
  69. keym1BC=$+1
  70.         LD BC,0
  71. KEYMnPUT
  72.         INC E
  73.         RR C
  74.         DJNZ KEYM1
  75. keym0HL=$+1
  76.         LD HL,0
  77.         INC HL
  78. keym0BC=$+1
  79.         LD BC,0
  80.         RRC B ;next halfrow
  81.         jr C,KEYM0
  82.  
  83. ;blowing
  84.         ld a,(keyrepcounter)
  85.         OR A
  86.         RET Z
  87.         DEC A
  88.         jr Z,KEYREPSEND
  89. KEYREPSETCNT
  90.         LD (keyrepcounter),A
  91.         RET
  92.  
  93. ;C0=press(1)/release(0)
  94. ;A=code
  95. ;B=scancode without shifts
  96. KEYREP
  97.         IF 1==0
  98.         push af
  99.         push bc
  100.         push de
  101.         push hl
  102.         ld a,b
  103.         add a,'A'      
  104.         ld c,a
  105.         ld b,0
  106.         call KEYQUEUEPUT
  107.         ld a,(keyrepscancode)
  108.         add a,'A'
  109.         ld c,a
  110.         ld b,0
  111.         call KEYQUEUEPUT
  112.         pop hl
  113.         pop de
  114.         pop bc
  115.         pop af
  116.         ENDIF
  117.         RR C ;NC=release
  118.         jr C,KEYREPPRESS
  119. ;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)
  120.          cp csss
  121.          jr nz,KEYREPRELEASE
  122. keyrepkey=$+1
  123.         cp 0
  124.         ld a,csnoshifts
  125.         LD (keyrepkey),A ;forget "ext" to avoid "ext, cs" work as ext, ext
  126.         jr nz,KEYREPSEND
  127.         ld a,csss
  128.         jr KEYREPSENDA
  129. KEYREPRELEASE
  130. ;if the repeated key (without shifts) is released
  131. ;then stop key repeat
  132. ;or else ignore
  133.        LD A,B ;scancode without shifts
  134. keyrepscancode=$+1
  135.        SUB -1
  136.         RET NZ
  137.       ;XOR A
  138.        JR KEYREPSETCNT
  139. KEYREPPRESS
  140.         cp cssspress ;=csss
  141.         jr nz,KEYREPPRESSncsss
  142. keyrepcounter=$+1
  143.         LD d,0
  144.         inc d
  145.         dec d
  146.         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)
  147.         ;z
  148. KEYREPPRESSncsss
  149.        LD (keyrepkey),A
  150.         ret z ;no "ext" keypress, only release
  151.        SUB cs1;'1'-32
  152.        CP 2
  153.        jr C,KEYREPSEND ;no autorep for cs1..2
  154.        LD A,B ;scancode without shifts
  155.        LD (keyrepscancode),A
  156.         LD A,14;10
  157.         LD (keyrepcounter),A
  158. KEYREPSEND
  159.          ld a,(keyrepkey)
  160. KEYREPSENDA
  161.          
  162. ;A = code ;[(cs+1 was encoded as '1'-32)]
  163. ;csnoshifts means CS release
  164. ;idle: cs1..2 start, csnoshifts skip, others pass by
  165. ;working: cs0..9 add, others end (1,2 add cs0)
  166. KEYALTGR
  167. altgrN=$+1
  168.         LD BC,#100 ;C=AltGr code (0=idle), B=1 (codes)
  169.          ld e,a ;current key
  170.            sub cs0;'0'-32
  171.            jr z,KEYALTGRcs0
  172.         SUB cs1-1 -cs0
  173. KEYALTGRcs0
  174.        LD D,A ;0..9 in good case
  175.        INC C
  176.        DEC C
  177.        jr Z,KEYALTGR_IDLE
  178.         CP 10
  179.        LD A,C
  180.         jr NC,KEYALTGRPUT ;stop AltGr (csnoshifts or wrong key) ;a=final code
  181.         ADD A,A
  182.         ADD A,A
  183.         ADD A,C
  184.         ADD A,A ;D*10
  185.         ADD A,D
  186. KEYALTGRN
  187.         LD (altgrN),A
  188.         RET
  189. KEYALTGR_IDLE
  190. ;A=1..2 in good case
  191.         DEC A
  192.         CP 2 ;CY=1: cs1/cs2
  193.         INC A
  194.         jr C,KEYALTGRN ;start AltGr
  195.          ld a,e ;current key
  196.         jr KEYALTGRPUT_NO1_2 ;for passing extA(=1),extB(=2)
  197. KEYALTGRPUT
  198. ;cs release gives final code here (=1 or 2 for single keypress of cs1 or cs2)
  199.         cp 3
  200.         jr nc,$+5
  201.             add a,cs1-1
  202. KEYALTGRPUT_NO1_2
  203.             inc b ;control keys
  204.         or a;CP csnoshifts
  205.         RET Z ;avoid NOKEY
  206.         LD C,A
  207.        XOR A
  208.        LD (altgrN),A ;idle
  209.  
  210. ;BC=code (B=2 => might be control code) (B=1 means AltGr symbol, for KEYLANG passby)
  211. KEYSWITCH
  212.        DEC B
  213.        jr Z,KEYSWPASS ;B=0 ;AltGr symbol, for KEYLANG passby
  214.         LD A,C
  215.         ;push af
  216.         ;push bc
  217.         ;ld bc,'a'
  218.         ;ld c,a
  219.         ;call KEYQUEUEPUT
  220.         ;pop bc
  221.         ;pop af
  222. keyswstate=$+1
  223.         LD HL,#100 ;H=язык=1..numlangs (H=numlangs при graph)
  224.                    ;L0=CapsLock
  225.         CP cs2
  226.         jr Z,KEYSWCAPSLOCK
  227.         CP cs1
  228.         jr Z,KEYSWLANG
  229.         CP ext1
  230.         jr NZ,KEYSWPASS
  231. KEYSWGRAPH
  232.         LD A,H
  233.         LD H,numlangs
  234.         CP H ;graph уже включен?
  235.         jr NZ,KEYSWOK ;нет - включаем, иначе DEC H
  236. KEYSWLANG
  237.         DEC H
  238.         jr NZ,$+4
  239.         LD H,numlangs-1
  240.         DEC L
  241. KEYSWCAPSLOCK
  242.         INC L
  243. KEYSWOK
  244.         LD (keyswstate),HL
  245. ;pass key to make possible to redraw blinking cursor
  246. KEYSWPASS
  247.  
  248. ;BC=code (B=0 means AltGr symbol, for KEYLANG passby) (B=1 for usual keys)
  249. KEYLANG
  250.         INC B
  251.         DEC B
  252.         jr Z,KEYLANGPASS ;B=0: symbol from ALTGR
  253. ;B=1
  254.         ;CALL KEYQUEUEPUT ;BC=code
  255.         ld (keyqueueput_codenolang),bc
  256. KEYLANG_REPEAT
  257.         LD A,C
  258.         LD (keylangcode),A
  259.          sub ext1 ;how it worked in ACEdit without this check?
  260.          jr z,KEYLANGPASS_A ;B=1 (control key) ;a=0=NOKEY => c
  261.          sub cs1-ext1 ;how it worked in ACEdit without this check?
  262.          jr z,KEYLANGPASS_A ;B=1 (control key) ;a=0=NOKEY => c
  263.          sub cs2-cs1 ;how it worked in ACEdit without this check?
  264.          jr z,KEYLANGPASS_A ;B=1 (control key) ;a=0=NOKEY => c
  265.         SUB 0xff&(32-cs2)
  266.         CP 95
  267.         jr NC,KEYLANGPASS ;B=1 (control key)
  268. rustrdisp=$+1
  269.        LD DE,0 ;D=0
  270.        INC E
  271.        DEC E
  272.        jr NZ,KEYLANG_SHV2 ;second key of combination?
  273. keylangcode=$+1
  274.         LD BC,0 ;B=0, C=code
  275.         LD DE,(keyswstate)
  276. ;BC=code
  277.         DEC D
  278.         jr Z,KEYL_ENG ;B=0
  279.         DEC D
  280.         jr NZ,KEYL_GRAPH ;B=0
  281. KEYL_RUSTR
  282. ;B=0
  283.        IF multikbd
  284. kmode=$+1
  285.         LD A,1
  286.         CP kR
  287.         jr Z,KEYL_SHVERTY
  288.         CALL RERUS
  289.         JR KEYLANGPUT ;B=0
  290. KEYL_SHVERTY
  291.        ENDIF
  292.         LD A,C
  293.         CP 64
  294.         jr C,KEYLANGPUT ;B=0
  295.         LD HL,tkeyl_rustr
  296.         ADD HL,BC
  297.         LD C,(HL)
  298.         LD A,C
  299.         CP 64
  300.         jr NC,KEYLANGPUT ;B=0
  301.        ;LD (rustrdisp),BC ;B=0
  302.       ;LD A,C
  303.        LD (rustrdisp),A
  304.         ;RET
  305.         ld c,b ;b=0 ;put keylang=0 with current keynolang
  306.         jr KEYLANGQ
  307.        
  308. KEYLANG_SHV2
  309.         LD (rustrNEW),BC
  310.        LD A,C;(rustrNEW)
  311.       ;LD (rustrNEW),A
  312. ;rustrdisp=$+1
  313.        ;LD DE,0 ;D=0
  314.         LD HL,tkeyl_rustrc
  315.         ADD HL,DE
  316.         LD C,(HL) ;len
  317.        LD B,D ;=0
  318.         INC HL
  319.         LD E,C
  320.         CPIR
  321.         LD C,E ;B=0
  322.         ADD HL,BC
  323.         jr Z,KEYLANGCOMBO ;combination entered (such as qq)
  324. ;no such combination - take symbol #len
  325.        LD A,(HL)
  326.        CALL case
  327.        LD C,A
  328.         CALL KEYQUEUEPUT ;B=0
  329. rustrNEW=$+1
  330.        LD BC,0 ;B=0
  331.        XOR A
  332.        LD (rustrdisp),A
  333.          ld h,a
  334.          ld l,a
  335.          ;ld (keyqueueput_codenolang),hl ;no keynolang for 2nd symbol
  336.         JR KEYLANG_REPEAT ;doubling and recoding the 2nd symbol
  337. KEYL_GRAPH
  338. ;B=0
  339. ;'0' -> 0030
  340. ;'1' -> 0031
  341. ;'2' -> 0032
  342. ;'3' -> 0033
  343. ;'4' -> 0034
  344. ;'a' -> 0061
  345. ;do "case" first!!!
  346.        LD A,C
  347.        CALL case
  348.        LD C,A
  349.         LD HL,tkeyl_graph
  350.         ADD HL,BC
  351.         LD C,(HL)
  352.         jr KEYLANGPASS
  353.        
  354. KEYLANGCOMBO
  355.         DEC HL
  356.         LD C,(HL)
  357. KEYL_ENG ;B=0
  358. KEYLANGPUT ;B=0
  359.        LD A,C
  360.        CALL case
  361. KEYLANGPASS_A
  362.        LD C,A
  363. KEYLANGPASS
  364.        XOR A
  365.        LD (rustrdisp),A
  366. KEYLANGQ
  367.  
  368. ;BC=code (B=1 => control key)
  369. KEYQUEUEPUT
  370. keyqueueN=$+1
  371.         LD A,0 ;decreased AFTER reading from queue
  372.         CP keyqueuemax
  373.         RET Z ;no room
  374.         INC A
  375.         LD (keyqueueN),A
  376. ;ALTGR codes: b=0, c=0..255
  377. ;letters: b=0, c>=32
  378. ;control codes: b=1, c=0..31, #bx, #cx, #dx, #fx
  379.        
  380. ;result: TODO b=1, c=#8x, #9x for ALTGR codes 0..31???
  381. keyqueuehead=$+1
  382.         LD HL,tkeyqueue
  383.         LD (HL),C
  384.         INC HL
  385.         LD (HL),B ;B=0: letter, B=1: control key
  386.         CALL KEYQUEUEINCHL
  387. keyqueueput_codenolang=$+1
  388.         ld bc,0
  389.         LD (HL),C
  390.         INC HL
  391.         LD (HL),B ;B=0: symbol from ALTGR, B=1: other keys
  392.         CALL KEYQUEUEINCHL
  393.         LD (keyqueuehead),HL
  394.         RET
  395.  
  396. tkeydecodeext
  397.         DB key_extspace,ssnoshifts,extM,extN,extB
  398.         DB key_extenter,extL,extK,extJ,extH
  399.         DB extP,extO,extI,extU,extY
  400.         DB ext0,ext9,ext8,ext7,ext6
  401.         DB ext1,ext2,ext3,ext4,ext5
  402.         DB extQ,extW,extE,extR,extT
  403.         DB extA,extS,extD,extF,extG
  404.         DB cssspress,extZ,extX,extC,extV
  405. tkeydecode
  406.         DB " ",ssnoshifts,"mnb"
  407.         DB key_enter,"lkjh"
  408.         DB "poiuy"
  409.         DB "09876"
  410.         DB "12345"
  411.         DB "qwert"
  412.         DB "asdfg"
  413.         DB csss,"zxcv"
  414. tkeydecodecs
  415.         DB key_esc,ssnoshifts,"MNB"
  416.         DB key_csenter,"LKJH"
  417.         DB "POIUY"
  418.         ;DB '0'-32,'9'-32,'8'-32,'7'-32,'6'-32
  419.         ;DB '1'-32,'2'-32,'3'-32,'4'-32,'5'-32
  420.         db cs0,cs9,cs8,cs7,cs6
  421.         db cs1,cs2,cs3,cs4,cs5
  422.         DB "QWERT"
  423.         DB "ASDFG"
  424.         DB csnoshifts,"ZXCV"
  425. tkeydecodess
  426.         DB key_ssspace,ssnoshifts,".,*"
  427.         DB ssnoshifts,"=+-^"
  428.         DB 34,";",ssI,"]["
  429.         DB "_)('&"
  430.         DB "!@#$%"
  431.         DB ssQ,ssW,ssE,"<>"
  432.         DB "~|",#5c,"{}"
  433.         DB csss,":`?/" ;in fact csss keypress is taken from tkeydecodeext, csss release from tkeydecodecs
  434. tkeymatrixstate
  435.         DS 8,#FF ;initially nothing pressed
  436.  
  437. tkeyl_graph=$-32
  438.         DB 32,14,34,16,17,18,19,20,"()*+,-./"
  439.         DB 12,1,2,3,4,5,6,7,8,11,":;єўЄ?"
  440.         DB 15,"╠╧╝╣╗╞╪╡▄▀■¤№╛▌▐╔╒╬╤█╘╦╩╕╚[",#5c,"]^_"
  441.         DB "`├╨┘┤┐╟╫╢─░▒▓√╜║═┌╓┼╥│╙┬┴╖└{|}~"
  442. tkeyl_rustr=$-64
  443.         DB "@АБ",rustrCdisp
  444.         DB "ДЕФГ",rustrHdisp,"И",rustrJdisp
  445.         DB "КЛМНОП",rustrQdisp
  446.         DB "РСТУЖВЬЫЗ[",#5c,"]^_"
  447.         DB "`аб",rustrcdisp
  448.         DB "дефг",rustrhdisp,"и",rustrjdisp
  449.         DB "клмноп",rustrqdisp
  450.         DB "рстужвьыз{|}~"
  451.  
  452. tkeyl_rustrc=$-1 ;to avoid zero displacements
  453. rustrhdisp=$-tkeyl_rustrc
  454.         DB 1,"h","э","х"
  455. rustrHdisp=$-tkeyl_rustrc
  456.         DB 1,"H","Э","Х"
  457. rustrqdisp=$-tkeyl_rustrc
  458.         DB 1,"q","щ","ш"
  459. rustrQdisp=$-tkeyl_rustrc
  460.         DB 1,"Q","Щ","Ш"
  461. rustrcdisp=$-tkeyl_rustrc
  462.        IF ukr
  463.         DB 2,"gc",#F3,"ц","ч"
  464.        ELSE
  465.         DB 1,"c","ц","ч"
  466.        ENDIF
  467. rustrCdisp=$-tkeyl_rustrc
  468.        IF ukr
  469.         DB 2,"GC",#F2,"Ц","Ч"
  470.        ELSE
  471.         DB 1,"C","Ц","Ч"
  472.        ENDIF
  473. rustrjdisp=$-tkeyl_rustrc
  474.        IF ukr
  475.         DB 7,"eyiaouj",#F5,#F7,#F9,"яёюъ","й"
  476.        ELSE
  477.         DB 4,"aouj","яёюъ","й"
  478.        ENDIF
  479. rustrJdisp=$-tkeyl_rustrc
  480.         DISPLAY $-tkeyl_rustrc,"<64"
  481.        IF ukr
  482.         DB 7,"EYIAOUJ",#F4,#F6,#F8,"ЯЁЮЪ","Й"
  483.        ELSE
  484.         DB 4,"AOUJ","ЯЁЮЪ","Й"
  485.        ENDIF
  486.  
  487.        IF kZ
  488. rt
  489.         DB "ЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧъ"
  490.        ENDIF
  491.        IF kJ
  492. rtjcuk
  493.         DB "@ФИСВУАПРШОЛДЬТЩЗЙКЫЕГМЦЧНЯ[",#5c,"]^_"
  494.        ENDIF
  495. RERUS
  496. ;in: C=code (32..126), A=kmode
  497. ;out: C=code
  498. ;keeps B
  499.         LD D,C ;code
  500.        IF kZ
  501.         LD HL,rt
  502.        ENDIF
  503.        IF kJ
  504.         IF multikbd
  505.         CP NkJ
  506.         jr NZ,rERUSnJCUK
  507.         ENDIF
  508.         LD HL,rtjcuk
  509.         LD A,D ;code
  510.         LD C,'б'
  511.         CP '!'
  512.         RET Z
  513.         LD C,'ж'
  514.         CP '@'
  515.         RET Z
  516.         LD C,'х'
  517.         SUB '#'
  518.         RET Z
  519.         LD C,'э'
  520.         DEC A ;'$'
  521.         RET Z
  522.         INC C ;'ю'
  523.         DEC A ;'%'
  524.         RET Z
  525. rERUSnJCUK ;
  526.        ENDIF
  527.         LD A,D ;code (32..126)
  528.         LD C,'ё'
  529.         CP '&'
  530.         RET Z
  531.         LD C,D
  532.         BIT 6,D ;code
  533.         RET Z ;code <64 (not letter) - return old code
  534. ;A=code (64..126)
  535.         AND 31
  536.         ADD A,L
  537.         LD L,A
  538.         jr NC,$+3
  539.         INC H
  540.         LD A,(HL) ;capital Russian
  541.         BIT 7,A
  542.         RET Z ;not a letter in the table - return old code
  543.         LD C,A ;capital Russian
  544.         BIT 5,D ;code
  545.         RET Z ;C contained capital letter, return capital
  546.         CALL RECAP
  547.         LD C,A ;small Russian
  548.         RET
  549.  
  550. CHECKCAPSLOCK
  551.         PUSH HL
  552.         LD HL,keyswstate
  553.         BIT 0,(HL)
  554.         POP HL
  555.         RET
  556. case
  557.         CALL CHECKCAPSLOCK
  558.         RET Z
  559. RECAP
  560.         CP 0xf2;je'Є'
  561.         RET NC
  562.         XOR 1
  563.         CP 0xf0;jo'Ё'
  564.         RET NC
  565.         XOR 1
  566.         CP 0xe0;'р'
  567.         jr NC,BECAPRL
  568.         CP 0xb0;'-'
  569.         RET NC
  570.         CP 0xa0;'а'
  571.         jr NC,BECAPOK
  572.         CP 0x90;'Р'
  573.         jr NC,BECAPRL
  574.         CP 0x80;'А'
  575.         jr NC,BECAPOK
  576.         CP '@'
  577.         RET Z
  578.         CP '_'
  579.         RET Z
  580.         CP 'A'
  581.         RET C
  582.         CP '{'
  583.         RET NC
  584.         CP '['
  585.         jr C,$+5
  586.         CP 'a'
  587.         RET C
  588. BECAPOK XOR 80
  589. BECAPRL XOR #70
  590.         RET
  591.  
  592. KEYQUEUEINCHL
  593.         INC HL
  594.         LD A,L
  595.         CP tkeyqueueend&0xff
  596.         RET NZ
  597.         LD HL,tkeyqueue
  598.         RET
  599.        
  600. tkeyqueue
  601.         DS 4*keyqueuemax
  602. tkeyqueueend
  603.  
  604. PEEKKEY
  605.         LD A,(keyqueueN)
  606.         OR A
  607.         ld h,a
  608.         RET Z ;a=NOKEY, h=0
  609.         LD HL,(keyqueuetail)
  610.         LD a,(HL)
  611.         INC HL
  612.         LD h,(HL)
  613.         ret
  614.        
  615. GETKEY
  616. ;out: ha=key (NOKEY=none), bc=keynolang keeps de,l
  617. ;H0=1 for control codes, H0=0 for symbols
  618. ;TODO уфх-Єю т H фюсртшЄ№ сшЄ√ ЁхушёЄЁр ъыртшрЄєЁ√
  619.         LD A,(keyqueueN)
  620.         OR A
  621.         ld h,a
  622.          ld b,a
  623.          ld c,a
  624.         RET Z ;a=NOKEY, h=0, bc=0
  625.         PUSH de
  626.         PUSH HL
  627. keyqueuetail=$+1
  628.         LD HL,tkeyqueue
  629. ;2 bytes with language
  630. ;2 bytes without language
  631.         LD e,(HL)
  632.         INC HL
  633.         LD d,(HL) ;keylang
  634.         CALL KEYQUEUEINCHL
  635.         LD c,(HL)
  636.         INC HL
  637.         LD b,(HL) ;keynolang
  638.         CALL KEYQUEUEINCHL
  639.         LD (keyqueuetail),HL
  640.         LD HL,keyqueueN
  641.         DEC (HL) ;atomic!!! (or we can miss keyqueueN increase)
  642.                  ;after reading!!! (or it might be overwritten while reading)
  643.         POP HL
  644.         ld h,d ;keylang HSB
  645.         ld a,e ;keylang LSB
  646.         pop de
  647.         RET
  648.  
  649. KEY_PUTREDRAW
  650. ;ўшёЄшь юўхЁхф№ ъыртшрЄєЁ√
  651.         call GETKEY
  652.         or c
  653.         jr nz,KEY_PUTREDRAW
  654. ;ъырф╕ь ъэюяъє яхЁхЁшёютъш, хёыш х╕ эхЄ т юўхЁхфш
  655.          ;;ld a,key_redraw
  656.          ;;ld (curkey),a
  657.          ;call PEEKKEY ;ld a,(curkey) ;TODO ёьюЄЁхЄ№ уюыютє юўхЁхфш, р эх їтюёЄ
  658.          ;cp key_redraw
  659.          ;ret z
  660.          ld bc,key_redraw
  661.          ld (keyqueueput_codenolang),bc
  662.          jp KEYQUEUEPUT ;хёыш яхЁхъы■ўшышё№ эр эхръЄштэє■ чрфрўє, Єю эхъюьє яЁюўшЄрЄ№ ъюф!!
  663.