Top secrets sources NedoPC pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

#include "std.h"

#include "emul.h"
#include "vars.h"
#include "dx.h"
#include "tape.h"
#include "atm.h"
#include "memory.h"
#include "input.h"
#include "inputpc.h"

#include "util.h"

//=============================================================================
static unsigned char pastekeys[0x80-0x20] =
{
    // s     !     "     #     $     %     &     '     (     )     *     +     ,     -   .       /
    0x71, 0xB1, 0xD1, 0xB3, 0xB4, 0xB5, 0xC5, 0xC4, 0xC3, 0xC2, 0xF5, 0xE3, 0xF4, 0xE4, 0xF3, 0x85,
    // 0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?
    0x41, 0x31, 0x32, 0x33, 0x34, 0x35, 0x45, 0x44, 0x43, 0x42, 0x82, 0xD2, 0xA4, 0xE2, 0xA5, 0x84,
    // @     A     B     C     D     E     F     G     H     I     J     K     L     M     N     O
    0xB2, 0x19, 0x7D, 0x0C, 0x1B, 0x2B, 0x1C, 0x1D, 0x6D, 0x5B, 0x6C, 0x6B, 0x6A, 0x7B, 0x7C, 0x5A,
    // P     Q     R     S     T     U     V     W     X     Y     Z     [     \     ]     ^     _
    0x59, 0x29, 0x2C, 0x1A, 0x2D, 0x5C, 0x0D, 0x2A, 0x0B, 0x5D, 0x0A, 0xD5, 0x93, 0xD4, 0xE5, 0xC1,
    // `     a     b     c     d     e     f     g     h     i     j     k     l     m     n     o
    0x83, 0x11, 0x75, 0x04, 0x13, 0x23, 0x14, 0x15, 0x65, 0x53, 0x64, 0x63, 0x62, 0x73, 0x74, 0x52,
    // p     q     r     s     t     u     v     w     x     y     z     {     |     }     ~
    0x51, 0x21, 0x24, 0x12, 0x25, 0x54, 0x05, 0x22, 0x03, 0x55, 0x02, 0x94, 0x92, 0x95, 0x91, 0xC4
};  //`=0x83, 127=' - Alone Coder
//=============================================================================


//=============================================================================
static unsigned char ruspastekeys[64] =
{
    'A','B','W','G','D','E','V','Z','I','J','K','L','M','N','O','P',
    'R','S','T','U','F','H','C','^','[',']',127,'Y','X','\\',64,'Q',
    'a','b','w','g','d','e','v','z','i','j','k','l','m','n','o','p',
    'r','s','t','u','f','h','c','~','{','}','_','y','x','|','`','q'
};  //Alone Coder
//=============================================================================


//=============================================================================
void K_INPUT::clear_zx()
{
    size_t i;
    //-------------------------------------------------------------------------
    for(i = 0; i < _countof(kbd_x4); i++)
        kbd_x4[i] = -1U;
    //-------------------------------------------------------------------------
}
//=============================================================================


//=============================================================================
inline void K_INPUT::press_zx(unsigned char key)
{
    //-------------------------------------------------------------------------
    if (key & 0x08)
        kbd[0] &= ~1; // caps
    //-------------------------------------------------------------------------
    if (key & 0x80)
        kbd[7] &= ~2; // sym
    //-------------------------------------------------------------------------
    if (key & 7)
        kbd[(key >> 4) & 7] &= ~(1 << ((key & 7) - 1));
    //-------------------------------------------------------------------------
}
//=============================================================================

// #include "inputpc.cpp"

//=============================================================================
bool K_INPUT::process_pc_layout()
{
    for (unsigned i = 0; i < pc_layout_count; i++)
    {
        if (kbdpc[pc_layout[i].vkey] & 0x80)
        {
            press_zx((( kbdpc[ DIK_LSHIFT] | kbdpc[ DIK_RSHIFT]) & 0x80)  ?  pc_layout[i].shifted :
                                                                           pc_layout[i].normal);
            return true;
        }
    }
    return false;
}
//=============================================================================


//=============================================================================
void K_INPUT::make_matrix()
{
    unsigned char altlock = conf.input.altlock    ?     (kbdpc[DIK_LMENU] | kbdpc[DIK_RMENU]) & 0x80 :
                                                        0;
    size_t i;

    kjoy = 0xFF;
    fjoy = 0xFF;
   
    //-------------------------------------------------------------------------
    switch (keymode)
    {
        //---------------------------------------------------------------------
        case KM_DEFAULT:
            //-----------------------------------------------------------------
            clear_zx();
            //-----------------------------------------------------------------
            if (!altlock)
            {
                if (!conf.input.keybpcmode || !process_pc_layout())
                {
                    for (i = 0; i < VK_MAX; i++)
                    {
                        if (kbdpc[i] & 0x80)
                        {
                            *(inports[i].port1) &= inports[i].mask1;
                            *(inports[i].port2) &= inports[i].mask2;
                            /*
                            if(kbd[6] == 0xFE)
                                __debugbreak();
                            */

                        }
                    }
                }
            }
            //-----------------------------------------------------------------
            if (conf.input.fire)
            {
                //-------------------------------------------------------------
                if (!--firedelay)
                {
                    firedelay = conf.input.firedelay;
                    firestate ^= 1;
                }
                //-------------------------------------------------------------
                zxkeymap *active_zxk = conf.input.active_zxk;
                if (firestate)
                    *(active_zxk->zxk[conf.input.firenum].port) &= active_zxk->zxk[conf.input.firenum].mask;
                //-------------------------------------------------------------
            }
            //-----------------------------------------------------------------
        break;
        //---------------------------------------------------------------------
        case KM_KEYSTICK:
            //-----------------------------------------------------------------
            for (i = 0; i < _countof(kbd_x4); i++)
                kbd_x4[i] = rkbd_x4[i];
            //-----------------------------------------------------------------
            if (stick_delay)
            {
                stick_delay--;
                altlock = 1;
            }
            //-----------------------------------------------------------------
            if (!altlock)
            {
                for (i = 0; i < VK_MAX; i++)
                {
                    if (kbdpc[i] & 0x80)
                    {
                        *(inports[i].port1) ^= ~inports[i].mask1;
                        *(inports[i].port2) ^= ~inports[i].mask2;
                    }
                }
            }
            //-----------------------------------------------------------------
            if ((kbd_x4[0] ^ rkbd_x4[0]) | (kbd_x4[1] ^ rkbd_x4[1]))
                stick_delay = 10;
            //-----------------------------------------------------------------
        break;
        //---------------------------------------------------------------------
        case KM_PASTE_HOLD:
        {
            clear_zx();
            //-----------------------------------------------------------------
            // caps
            if (tdata & 0x08)
                kbd[0] &= ~1;
            //-----------------------------------------------------------------
            // sym
            if (tdata & 0x80)
                kbd[7] &= ~2;
            //-----------------------------------------------------------------
            if (tdata & 7)
                kbd[(tdata >> 4) & 7] &= ~(1 << ((tdata & 7) - 1));
            //-----------------------------------------------------------------
            if (tdelay)
            {
                tdelay--;
                break;
            }
            //-----------------------------------------------------------------
            tdelay = conf.input.paste_release;
            //-----------------------------------------------------------------
            if (tdata == 0x61)
                tdelay += conf.input.paste_newline;
            //-----------------------------------------------------------------
            keymode = KM_PASTE_RELEASE;
            //-----------------------------------------------------------------
            break;
        }
        //---------------------------------------------------------------------
        case KM_PASTE_RELEASE:
        {
            clear_zx();
            //-----------------------------------------------------------------
            if (tdelay)
            {
                tdelay--;
                break;
            }
            //-----------------------------------------------------------------
            if (textsize == textoffset)
            {
                keymode = KM_DEFAULT;
                free(textbuffer);
                textbuffer = nullptr;
                break;
            }
            //-----------------------------------------------------------------
            tdelay = conf.input.paste_hold;
            unsigned char kdata = textbuffer[textoffset++];
            //-----------------------------------------------------------------
            if (kdata == 0x0D)
            {
                //-------------------------------------------------------------
                if (textoffset < textsize && textbuffer[textoffset] == 0x0A)
                    textoffset++;
                //-------------------------------------------------------------
                tdata = 0x61;
            }
            //-----------------------------------------------------------------
            else
            {
                //-------------------------------------------------------------
                if (kdata == 0xA8)
                    kdata = 'E';        //Alone Coder (big YO)
                //-------------------------------------------------------------
                if ((kdata >= 0xC0)||(kdata == 0xB8)) //RUS
                {
                    //pressedit=
                    //0 = press edit, pressedit++, textoffset--
                    //1 = press letter, pressedit++, textoffset--
                    //2 = press edit, pressedit=0
                    switch (pressedit)
                    {
                        //-----------------------------------------------------
                        case 0:
                        {
                            tdata = 0x39;
                            pressedit++;
                            textoffset--;
                            break;
                        };
                        //-----------------------------------------------------
                        case 1:
                        {
                            if (kdata == 0xB8)
                                kdata = '&';
                            else
                                kdata = ruspastekeys[kdata - 0xC0];
                            tdata = pastekeys[kdata - 0x20];
                            pressedit++;
                            textoffset--;
                            break;
                        }
                        //-----------------------------------------------------
                        case 2:
                        {
                            tdata = 0x39;
                            pressedit = 0;
                        };
                        //-----------------------------------------------------
                    };
                    //---------------------------------------------------------
                    if (!tdata)
                        break; // empty key
                    //---------------------------------------------------------
                } //Alone Coder
                //-------------------------------------------------------------
                else
                {
                    //---------------------------------------------------------
                    if (kdata < 0x20 || kdata >= 0x80)
                        break; // keep release state
                    //---------------------------------------------------------
                    tdata = pastekeys[kdata - 0x20];
                    //---------------------------------------------------------
                    if (!tdata)
                        break; // empty key
                    //---------------------------------------------------------
                }
            }
            //-----------------------------------------------------------------
            keymode = KM_PASTE_HOLD;
            break;
        }
        //---------------------------------------------------------------------
    } //switch (keymode)
    //-------------------------------------------------------------------------
   
    kjoy ^= 0xFF;
   
    //-------------------------------------------------------------------------
    if (conf.input.joymouse)
        kjoy |= mousejoy;
    //-------------------------------------------------------------------------
    for(i = 0; i < _countof(kbd_x4); i++)
        rkbd_x4[i] = kbd_x4[i];
    //-------------------------------------------------------------------------
    if (!conf.input.keymatrix)
        return;
    //-------------------------------------------------------------------------
    for (;;)
    {
        char done = 1;
        //---------------------------------------------------------------------
        for (size_t k = 0; k < _countof(kbd) - 1; k++)
        {
            //-----------------------------------------------------------------
            for (size_t j = k+1; j < _countof(kbd); j++)
            {
                if (((kbd[k] | kbd[j]) != 0xFF) && (kbd[k] != kbd[j]))
                {
                    kbd[k] = kbd[j] = (kbd[k] & kbd[j]);
                    done = 0;
                }
            }
            //---------------------------------------------------------------------
        }
        //---------------------------------------------------------------------
        if (done)
            return;
        //---------------------------------------------------------------------
    }
}
//=============================================================================


//=============================================================================

__inline int sign_pm( int a)
{
    return (a < 0)  ?  -1 :
                        1;
}

//=============================================================================

static u8 CapsLockState = 0;

//=============================================================================
char K_INPUT::readdevices()
{
    //-------------------------------------------------------------------------
    if (nokb) nokb--;           // NEDOREPO
    //-------------------------------------------------------------------------
    if (nomouse) nomouse--;
    //-------------------------------------------------------------------------
    kbdpc[ VK_JLEFT]  = 0;
    kbdpc[ VK_JRIGHT] = 0;
    kbdpc[ VK_JUP]    = 0;
    kbdpc[ VK_JDOWN]  = 0;
    kbdpc[ VK_JFIRE]  = 0;
    //-------------------------------------------------------------------------
    int i;
    //-------------------------------------------------------------------------
    for (i = 0;    i < 32;    i++)
        kbdpc[ VK_JB0 + i] = 0;
    //-------------------------------------------------------------------------
    if (active && dijoyst)
    {
        dijoyst->Poll();
        DIJOYSTATE js;
        readdevice( &js, sizeof js, (LPDIRECTINPUTDEVICE) dijoyst);
        //---------------------------------------------------------------------
        if ((signed short)js.lX < 0) kbdpc[ VK_JLEFT]  = 0x80;
        if ((signed short)js.lX > 0) kbdpc[ VK_JRIGHT] = 0x80;
        if ((signed short)js.lY < 0) kbdpc[ VK_JUP]    = 0x80;
        if ((signed short)js.lY > 0) kbdpc[ VK_JDOWN]  = 0x80;
        //---------------------------------------------------------------------
        for (i = 0;    i < 32;    i++)
        {
            if (js.rgbButtons[i] & 0x80)
                kbdpc[ VK_JB0 + i] = 0x80;
        }
        //---------------------------------------------------------------------
    }
    //-------------------------------------------------------------------------
   
    //-------------------------------------------------------------------------
    mbuttons = 0xFF;
    msx_prev = msx;
    msy_prev = msy;
    kbdpc[ VK_LMB] = 0;
    kbdpc[ VK_RMB] = 0;
    kbdpc[ VK_MMB] = 0;
    kbdpc[ VK_MWU] = 0;
    kbdpc[ VK_MWD] = 0;
    //-------------------------------------------------------------------------
 
    //-------------------------------------------------------------------------
    // Äëÿ êîñòûëÿ îò ñêàêàíèÿ êóðñîðà ïðè çàõâàòå ôîêóñà [NS] r0112
    //-------------------------------------------------------------------------
    //
    // ñîáñòâåííî ïðîáëåìà
    //
    // unreal                   êàê íàäî
    // 1                        1
    // .2                       .2
    // ..3                      ..3
    // ...4                     ...4
    // ....5                    ....5
    // .....6                   .....6
    //
    // ÏÎÒÅÐß ÔÎÊÓÑÀ
    //
    // .....6                   .....6
    // .....6                   .....6
    // .....6 = last            .....6
    //
    // ÂÎÑÒÀÍÎÂËÅÍÈÅ ÔÎÊÓÑÀ
    //
    // ..3 = first              .....6 = new    first = 3  last = 6     cor = (last - first) = (6-3) = 3
    // ...4                     ......7         new = 3 + cor
    // ....5                    .......8
    // .....6                   ........9
    //
    // äëÿ FPS øóòîðîâ ýòà ãàôíî - äèêèé àõòóíõ óáåâàòü íàõ!!!
    //
        static int cor_x = 0;
        static int cor_y = 0;
        static int first_new_x;
        static int first_new_y;
        static int last_msx;
        static int last_msy;
        static bool first_new_flag = TRUE;
    //-------------------------------------------------------------------------

    //-------------------------------------------------------------------------
    // Êóðñîð çàõâà÷åí
//  if ((conf.fullscr || conf.lockmouse))               // [NS]
//  if ((conf.fullscr || conf.lockmouse) && !nomouse)   // ORIG
//  if (conf.lockmouse && !nomouse)                     // HZ
    if ((conf.lockmouse) && !nomouse)   // [NS] r0112   // nomouse - âèäèìî çàäåðæêà äî íà÷àëà ââîäà ñ ìûøîâ
    {                                                   // òåïåðü ôóëë ñêðèíí íå çíà÷èò çàõâàò ìûøîâ!!!
        unsigned cl1;
        unsigned cl2;
        cl1 = unsigned( abs( msx - msx_prev)) * ay_reset_t / conf.frame;
        cl2 = unsigned( abs( msx - msx_prev));
        ay_x0 += int( cl2 - cl1) * sign_pm( msx - msx_prev);
        cl1 = unsigned( abs( msy - msy_prev)) * ay_reset_t / conf.frame;
        cl2 = unsigned( abs( msy - msy_prev));
        ay_y0 += int( cl2 - cl1) * sign_pm( msy - msy_prev);
        ay_reset_t = 0;

//      printf("%s\n", __FUNCTION__);

        //---------------------------------------------------------------------
        DIMOUSESTATE md;
        readmouse( &md);
        //---------------------------------------------------------------------
        if (conf.input.mouseswap)
        {
            unsigned char t = md.rgbButtons[ 0];
            md.rgbButtons[ 0] = md.rgbButtons[ 1];
            md.rgbButtons[ 1] = t;
        }
        //---------------------------------------------------------------------
        msx = md.lX;
        msy = -md.lY;
        //---------------------------------------------------------------------
        if (conf.input.mousescale >= 0)
        {
            msx *= (1 << conf.input.mousescale);        // ñäåëàòü íîðìàëüíûå êîýôèöèåíòû!!!
            msy *= (1 << conf.input.mousescale);
        }
        else
        {
            msx /= (1 << -conf.input.mousescale);
            msy /= (1 << -conf.input.mousescale);
        }

        //---------------------------------------------------------------------
        // ÊÎÑÒÛËÜ!!! (îò ñêàêàíèÿ êóðñîðà ïðè çàõâàòå ôîêóñà)          [NS] r0112
        //      //-------------------------------------------------------------
        //      // ëîâèì ñàìîå ïåðâîå çíà÷åíèå ïîñëå çàõâàòà ôîêóñà
                if (first_new_flag)
                {
                    first_new_x = msx;
                    first_new_y = msy;
                    cor_x = (last_msx - first_new_x);
                    cor_y = (last_msy - first_new_y);
                    first_new_flag = FALSE; // ôëàã ÷òîá áîëüøøå íå ëîâèòü
                }
                //-------------------------------------------------------------
                // êîððåêòèðóåì ñêàêàíèå
                msx += cor_x;  
                msy += cor_y;
        //---------------------------------------------------------------------
        if (md.rgbButtons[0])
        {
            mbuttons &= ~1;
            kbdpc[ VK_LMB] = 0x80;
        }
        //---------------------------------------------------------------------
        if (md.rgbButtons[1])
        {
            mbuttons &= ~2;
            kbdpc[ VK_RMB] = 0x80;
        }
        //---------------------------------------------------------------------
        if (md.rgbButtons[2])
        {
            mbuttons &= ~4;
            kbdpc[ VK_MMB] = 0x80;
        }
        //---------------------------------------------------------------------
        int wheel_delta = md.lZ - prev_wheel;
        prev_wheel = md.lZ;
//      if (wheel_delta < 0) kbdpc[VK_MWD] = 0x80;
//      if (wheel_delta > 0) kbdpc[VK_MWU] = 0x80;
//0.36.6 from 0.35b2
        //---------------------------------------------------------------------
        if (conf.input.mousewheel == MOUSE_WHEEL_KEYBOARD)
        {
            //-----------------------------------------------------------------
            if (wheel_delta < 0)
                kbdpc[ VK_MWD] = 0x80;
            //-----------------------------------------------------------------
            if (wheel_delta > 0)
                kbdpc[ VK_MWU] = 0x80;
            //-----------------------------------------------------------------
        }
        //---------------------------------------------------------------------
        if (conf.input.mousewheel == MOUSE_WHEEL_KEMPSTON)
        {
            if (wheel_delta < 0)
            {
        //      wheel -= 0x10;                          //0.39.0
                wheel += 0x10; //24.11.2021 Alone       //NEDOREPO
            }
            if (wheel_delta > 0)
            {
        //      wheel += 0x10;                          //0.39.0
                wheel -= 0x10; //24.11.2021 Alone       //NEDOREPO
            }
            mbuttons = (mbuttons & 0x0F) + (wheel & 0xF0);
        }
//~
    }   //if ((conf.fullscr || conf.lockmouse) && !nomouse)
    //-------------------------------------------------------------------------
    // Êóðñîð íåçàõâà÷åí
    else
    {
            //-----------------------------------------------------------------
            // ÊÓÑÎÊ ÊÎÑÒÛËß îò ñêàêàíèÿ êóðñîðà ïðè çàõâàòå ôîêóñà [NS] r0112
            //-----------------------------------------------------------------
            // ëîâèì ïîñëåäíåå çíà÷åíèå
            last_msx = msx;
            last_msy = msy;
            first_new_flag = TRUE; // âçâîäèì ëîâóøêó ïåðâîãî çíà÷åíèÿ
            //-----------------------------------------------------------------
    }
    //-------------------------------------------------------------------------
   
    //-------------------------------------------------------------------------
//      lastkey = process_msgs();       0.39.0
//      memset(kbdpc, 0, 256);  // Ìûøü è äæîéñòèê íå î÷èùàåì
    //-------------------------------------------------------------------------
    if (nokb)                   // NEDOREPO
    {
        memset( kbdpc, 0, 256); // Ìûøü è äæîéñòèê íå î÷èùàåì
    }
    //-------------------------------------------------------------------------
    else
    {
        //GetKeyboardState(kbdpc);

        //thims zxevo_ps/2
        //static unsigned char kbdpc_prev[ VK_MAX];     //NEDOREPO
        //      kbdpc_prev[] âûíåñåí â vars.cpp [NS]
        //---------------------------------------------------------------------
        //if (buffer_enabled && (!dbgbreak))
        if ((buffer_enabled || atm620_xt_keyb_buffer_enabled) && (!dbgbreak))   // [NS]
            memcpy( kbdpc_prev, kbdpc, sizeof( kbdpc));
        //---------------------------------------------------------------------
        ReadKeyboard( kbdpc);

// [NS]
/*
        // "Èñïðàâëåíèå" "çàëèïàíèÿ" CapsLock,
        // CapsLock ïðè îäíîêðàòíîì íàæàòèè âîçâðàùàåò âñåãäà 0x80, ïîêà íå áóäåò íàæàò ïîâòîðíî
        //      ÷î çà áðåä?
        u8 cl = kbdpc[DIK_CAPSLOCK];
        kbdpc[DIK_CAPSLOCK] ^= CapsLockState;   // åñëè íàæàò
                                                // îíî åãî ñðàçó ñáðîñèò â 0 î_Î
        CapsLockState = cl;
//

 [NS] ãîôíîàëîíîôèêñ äåëàåò õóèòó
 â èòîãå ëîã:

        caps press
                ps2_key 58 - key on

                ps2_key F0 - key off
                ps2_key 58

        caps unpress
                ps2_key 58 - key on

                ps2_key F0 - key off
                ps2_key 58

 êåïñ äðî÷èòñî 2 ðàçà ïî öåíå 1
 êåïñ íàæèìàåòñî è îòæèìàåòñî ïðè íàæàòèè
 è åùå ðàç íàæèìàåòñî è îòæèììàåòñî ïðè îòïóñêàíèè
 
 ÷òî òàêîå àëîíîâñêîå "îäíîêðàòíîå íàæàòèå" â óïîð íåïîíÿòíî
 
*/


        //---------------------------------------------------------------------
        if (buffer_enabled && (!dbgbreak))      //DimkaM fix
        {
            // çàòàëêèâàíèå ñêàíêîäîâ â áóôåð
            for (int i = 0;    i < sizeof( kbdpc);    i++)
            {
                // ps2
                if ((kbdpc[i] & 0x80) != (kbdpc_prev[i] & 0x80) && dik_scan[i])
                {
                    if (dik_scan[i] & 0x0100) input.buffer.Push( 0xE0);
                    if (kbdpc_prev[i] & 0x80) input.buffer.Push( 0xF0); //key off
                    input.buffer.Push( dik_scan[i] & 0x00FF);
                }
            }
        }       //NEDOREPO
        //---------------------------------------------------------------------
        if (atm620_xt_keyb_buffer_enabled && (!dbgbreak))       // [NS]
        {
            // çàòàëêèâàíèå ñêàíêîäîâ â áóôåð
            for (int i = 0;    i < sizeof( kbdpc);    i++)
            {
                // ATM 6.20 XT Keyb [NS]
                if ((kbdpc[i] & 0x80) != (kbdpc_prev[i] & 0x80) && atm620_xt_keyb_dik_scan[i])
                {
                    if (atm620_xt_keyb_dik_scan[i] & 0x0100) input.atm620_xt_keyb_buffer.Push( 0xE0);
                    //---------------------------------------------------------
                    //key off
                    if (kbdpc_prev[i] & 0x80)
                    {
                        input.atm620_xt_keyb_buffer.Push( (atm620_xt_keyb_dik_scan[i] & 0x00FF) | 0x01 );       //0x01 = 0x80
                    }
                    //---------------------------------------------------------
                    //key on
                    else
                    {
                        input.atm620_xt_keyb_buffer.Push( atm620_xt_keyb_dik_scan[i] & 0x00FF);
                    }
                    //---------------------------------------------------------
                }
            }
        }
        //---------------------------------------------------------------------
        /*
        // à çðÿ òóïî çàêîìåí÷åííî [NS]
        if (lastkey)            //NEDOREPO
        {
//[vv]          kbdpc[ lastkey] = 0x80;         ?????? [NS]
        }
        */

        //---------------------------------------------------------------------
    }   //else (nokb)
    //-------------------------------------------------------------------------
    lastkey = process_msgs();   // V_KEY
    //-------------------------------------------------------------------------
    // òê äàííûå îò process_msgs ìîãóò áûòü íå ñîãëàñîâàíû ñ kbdpc[]    [NS]
    // íóæíî çàïèñàòü â kbdpc[] ïîëó÷åííîå èç process_msgs
    if (lastkey)
    {
        //printf("win %02X\n", lastkey);
        //printf("oem %02X\n", key_down_oem_key);
        //printf("kbdpc %02X\n", key_down_kbdpc_key);
        kbdpc[ key_down_kbdpc_key] = 0x80;
    }
    //-------------------------------------------------------------------------
   
   
    // Ðåçóëüòàò íåñîâìåñòèì ñ kbdpc[] !!!!!
                                // è íå ñîãëàñîâàí
                                // â èòîãå lastkey ñîîáùàÿåò ÷òî êíîïêà íàæàòà
                                // à â kbdpc[] íèêàêîé êíîïêè íåò
                                // èíîãäà åå íåò â 100% ñëó÷àåâ !!!
                                // ÒÀÊÆÅ
                                // äî kbdpc íåäîõîäèò âèðòóàëüíàÿ êëàâèàòóðà!!!
                                // à âîò process_msgs äîñòàåò èç îíî êíîïêè !!!
                // òåïåðü process_msgs âîçâðàùàåò ãëîáàëüíûå
                // key_down_oem_key
                // key_down_v_key       - òîæå ÷òî è return
       
       
        // òóò íóæåí kbdpc[ lastkey] = 0x80;
        // ÍÎ lastkey íóæíî ïåðåâåñòè â ôîðìàò kbdpc !!!
        // èç âåíäîâîãî vk_key â xt
            //-----------------------------------------------------------------
            // òàêîé âàðèàíò ðàáîòàåò, íà âèä, õîðîøî
            // ÍÎ íåòó ïàóçû ìåæäó íàæàòèÿìè
            // à process_msgs() åùå è øëåò âåíäîâûé àâòîïîâòîð
            /*
            lastkey = 0;
            // 0 - nil key
            for (int i = 1;    i < sizeof( kbdpc);    i++)      // TZT [NS]
            {
                lastkey |= kbdpc[i];
            }
            */

            //-----------------------------------------------------------------
            // Òàê íå ðàáîòàåò àâòîïîâòîð
            // è íåâîçìîæíî ïîëëüçîâààòññî ääåáàãåððîì èòä
            /*
            lastkey = 0;
            // 0 - nil key
            for (int i = 1;    i < sizeof( kbdpc);    i++)      // TZT [NS]
            {
                //printf("%X ",kbdpc[i]);
                if ( (kbdpc[i] & 0x80) != (kbdpc_prev[i] & 0x80))       //ïî ôàêòó èçìåíåíèÿ
                {
                    lastkey |= kbdpc[i];
                }
            }
            */

            // ÇÀÏÎËÍÅÍÈÅ kbdpc_prev ÍÓÆÍÎ ÏÐÈÍÓÄÈÒÅËÜÍÎ ÂÊËÞ×ÀÒÜ !!!!!!!!
            //-----------------------------------------------------------------
           
           
            /*
            // ðàáî÷èé ñïîñîá íî íóæíà ãîâíîòàáëèöà
            unsigned char xt_like_lastkey = vk_key_2_xt_key_tab[ lastkey];
            //-----------------------------------------------------------------
            // ìåðæèì ñ åùå îäíèì èñòî÷íèêîì êíîïîê
            //    òóò íàäî äîáàâèòü åùå êîäà
            //    ÷òîá îòëè÷àòü íåîòëè÷àáåëüíûå êíîïêè
            //    òê ýòîò èñòî÷íèê êíîïîê ðàáîòàåò ñ âèðòóàëüíîé êëàâèàòóðîé !!!
            if (xt_like_lastkey)
            {
                kbdpc[ xt_like_lastkey] = 0x80;
            }
            //-----------------------------------------------------------------
            */

           


           
    //-------------------------------------------------------------------------
/* [vv]
   if (temp.win9x)
   {
      kbdpc[VK_LSHIFT] = kbdpcEX[0];
      kbdpc[VK_RSHIFT] = kbdpcEX[1];
      kbdpc[VK_LCONTROL] = kbdpcEX[2];
      kbdpc[VK_RCONTROL] = kbdpcEX[3];
      kbdpc[VK_LMENU] = kbdpcEX[4];
      kbdpc[VK_RMENU] = kbdpcEX[5];
   } //Dexus
*/

//-----------------------------------------------------------------------------

//    if (lastkey)
//    {
//                      //printf("%x",lastkey);
//                      printf("\nwin %x\n",lastkey);
//                      printf("new %x\n",xt_like_lastkey);
//    }
    //else              printf(".");
   
    return lastkey  ?   1 :
                        0;
}
//=============================================================================


//=============================================================================
void K_INPUT::aymouse_wr(unsigned char val)
{
    //-------------------------------------------------------------------------
    // reset by edge bit6: 1->0
    if (ayR14 & ~val & 0x40)
    {
        ay_x0 = ay_y0 = 8;
        ay_reset_t = cpu.t;
    }
    //-------------------------------------------------------------------------
    ayR14 = val;
}
//=============================================================================


//=============================================================================
unsigned char K_INPUT::aymouse_rd()
{
    unsigned coord;
    if (ayR14 & 0x40)
    {
        unsigned cl1 = unsigned(abs(msy - msy_prev)) * ay_reset_t / conf.frame;
        unsigned cl2 = unsigned(abs(msy - msy_prev)) * cpu.t / conf.frame;
        coord = unsigned(ay_y0 + int(cl2-cl1)*sign_pm(msy - msy_prev));
    }
    else
    {
        unsigned cl1 = unsigned(abs(msx - msx_prev)) * ay_reset_t / conf.frame;
        unsigned cl2 = unsigned(abs(msx - msx_prev)) * cpu.t / conf.frame;
        coord = unsigned(ay_x0 + int(cl2-cl1)*sign_pm(msx - msx_prev));
    }
/*
   int coord = (ayR14 & 0x40)?
     ay_y0 + 0x100 * (msy - msy_prev) * (int)(cpu.t - ay_reset_t) / (int)conf.frame:
     ay_x0 + 0x100 * (msx - msx_prev) * (int)(cpu.t - ay_reset_t) / (int)conf.frame;
//   if ((coord & 0x0F)!=8 && !(ayR14 & 0x40)) printf("coord: %X, x0=%4d, frame_dx=%6d, dt=%d\n", (coord & 0x0F), ay_x0, msx-msx_prev, cpu.t-ay_reset_t);
*/

   return 0xC0 | (coord & 0x0F) | u8(mbuttons << 4);
}
//=============================================================================




//
//
//


//=============================================================================
unsigned char K_INPUT::kempston_mx()
{
    int x = ((int(cpu.t) * msx) + (int(conf.frame - cpu.t) * msx_prev)) / int(conf.frame);
    //printf("x %X\n",x);
    return (unsigned char)x;
}
//=============================================================================
unsigned char K_INPUT::kempston_my()
{
    int y = ((int(cpu.t) * msy) + (int(conf.frame - cpu.t) * msy_prev)) / int(conf.frame);
    //printf("y %X\n",y);
    return (unsigned char)y;
}
//=============================================================================


//=============================================================================
unsigned char K_INPUT::read(unsigned char scan)
{
    unsigned char res = 0xBF | (tape_bit() & 0x40);
    kbdled &= scan;

    //-------------------------------------------------------------------------
    if (conf.atm.xt_kbd)
        return input.atm51.read(scan, res);
    //-------------------------------------------------------------------------
    for (int i = 0; i < 8; i++)
    {
        if (!(scan & (1<<i)))
            res &= kbd[i];
    }
    //-------------------------------------------------------------------------

/*
   if(res != 0xFF)
       __debugbreak();
*/


    return res;
}
//=============================================================================


//=============================================================================
// read quorum additional keys (port 7E)
u8 K_INPUT::read_quorum(u8 scan)
{
    u8 res = 0xFF;
    kbdled &= scan;
    //-------------------------------------------------------------------------
    for (int i = 0; i < 8; i++)
    {
        if (!(scan & (1<<i)))
            res &= kbd[8+i];
    }
    //-------------------------------------------------------------------------
    return res;
}
//=============================================================================


//=============================================================================
void K_INPUT::paste()
{
    free(textbuffer); textbuffer = nullptr;
    textsize = textoffset = 0;
    keymode = KM_DEFAULT;
    //-------------------------------------------------------------------------
    if (!OpenClipboard(wnd))
        return;
    //-------------------------------------------------------------------------
    HANDLE hClip = GetClipboardData(CF_TEXT);
    //-------------------------------------------------------------------------
    if (hClip)
    {
        void *ptr = GlobalLock(hClip);
        if (ptr)
        {
            keymode = KM_PASTE_RELEASE; tdelay = 1;
            textsize = unsigned(strlen((char*)ptr) + 1);
            memcpy(textbuffer = (unsigned char*)malloc(textsize), ptr, textsize);
            GlobalUnlock(hClip);
            // à ãäå êàêîéíèòü free ?
        }
    }
    //-------------------------------------------------------------------------
    CloseClipboard();
}
//=============================================================================


//=============================================================================
unsigned char ATM_KBD::read(unsigned char scan, unsigned char zxdata)
{
    unsigned char t;

    //-------------------------------------------------------------------------
    if (R7)
    {
        //---------------------------------------------------------------------
        if (R7 == 1)
            cmd = scan;
        //---------------------------------------------------------------------
        switch (cmd & 0x3F)
        {
            //-----------------------------------------------------------------
            case 1:
            {
                static const unsigned char ver[4] = { 6, 0, 1, 0 };
                R7 = 0;
                return ver[cmd >> 6];
            }
            //-----------------------------------------------------------------
            case 7:
                clear();
                R7 = 0;
                return 0xFF;    // clear data buffer in mode0
            //-----------------------------------------------------------------
            case 8:
                //-------------------------------------------------------------
                if (R7 == 2)
                {
                    mode = scan;
                    kR2 = 0;
                    R7 = 0;
                    return 0xFF;
                }
                //-------------------------------------------------------------
                R7++;
                return 8;
            //-----------------------------------------------------------------
            case 9:
                //-------------------------------------------------------------
                switch (cmd & 0xC0)
                {
                    //---------------------------------------------------------
                    case 0x00:
                        t = kR1;        //???? òàê è äîëæíî áûòü??? [NS]
                    //---------------------------------------------------------
                    case 0x40:
                        t = kR2;
                    //---------------------------------------------------------
                    case 0x80:
                        t = kR3;
                    //---------------------------------------------------------
                    case 0xC0:
                        t = kR4;
                    //---------------------------------------------------------
                }
                //-------------------------------------------------------------
                R7 = 0;
                return t;
            //-----------------------------------------------------------------
            case 10:
                kR3 |= 0x80;
                R7 = 0;
                return 0xFF;
            //-----------------------------------------------------------------
            case 11:
                kR3 &= 0x7F;
                R7 = 0;
                return 0xFF;
            //-----------------------------------------------------------------
//          case 12:            ????? [NS] øîýòà áûëî?
//              R7 = 0;
//              return 0xFF; // enter pause mode
            //-----------------------------------------------------------------
            case 13:
                // reset!
                this->reset();
                cpu.int_flags = cpu.ir_ = cpu.pc = 0;
                cpu.im = 0;
                comp.p7FFD = comp.flags = 0;
                set_atm_FF77(0,0);
                set_banks();
                break;
            //-----------------------------------------------------------------
            case 16:
            case 18:
            {
                SYSTEMTIME time;
                GetLocalTime(&time);
                R7 = 0;
                if (cmd == 0x10) return (BYTE)time.wSecond;
                if (cmd == 0x40) return (BYTE)time.wMinute;
                if (cmd == 0x80) return (BYTE)time.wHour;
                if (cmd == 0xC0) return (BYTE)time.wDay;
                if (cmd == 0x12) return (BYTE)time.wDay;
                if (cmd == 0x42) return (BYTE)time.wMonth;
                if (cmd == 0x82) return (BYTE)(time.wYear % 100);
                if (cmd == 0xC2) return (BYTE)(time.wYear / 100);
            }
            //-----------------------------------------------------------------
            case 17: // set time
            case 19: // set date
                //-------------------------------------------------------------
                if (R7 == 2)
                {
                    R7 = 0;
                }
                //-------------------------------------------------------------
                else
                {
                    R7++;
                }
                //-------------------------------------------------------------
                return 0xFF;
            //-----------------------------------------------------------------
        }
        //---------------------------------------------------------------------
        R7 = 0;
        return 0xFF;
    }
    //-------------------------------------------------------------------------
    if (scan == 0x55)
    {
        R7++;
        return 0xAA;
    }
    //-------------------------------------------------------------------------
    switch (mode & 3)
    {
        //---------------------------------------------------------------------
        // 0 - ðåæèì Spectrum KBD
        //      ýòîì ðåæèìå êîíòðîëëåð ýìóëèðóåò ïîäêëþ÷åíèå ê ïîðòó êëàâèàòóðû îáû÷íîé ìàòðèöû 5*8 êëàâèø.
        //     Êàæäîå íàæàòèå êëàâèøè ïðåîáðàçóåòñÿ â îäíî èëè äâà çàìûêàíèÿ â óçëàõ ýòîé ìàòðèöû.
        //     Ïðè ñêàíèðîâàíèè ïîðòà êëàâèàòóðû íà âûõîä âûäàåòñÿ êîä ñîîòâåòñòâóþùèé çàïðîøåííîé àäðåñíîé ëèíèè ìàòðèöû.
        //     Äîïîëíèòåëüíî ê ýòîìó êîäó äîáàâëÿåòñÿ êîä ñ÷èòàííûé ñ "ðîäíîãî" ïîðòà êëàâèàòóðû,
        //     ÷òî ïîçâîëÿåò ñ÷èòàòü ëèíèþ âõîäà ìàãíèòîôîííîãî èíòåðôåéñà è ñèãíàëû ñ äæîéñòèêîâ èëè ìåõàíè÷åñêîé êëàâèàòóðû.
        //     Äîáàâêà èäåò êîìàíäîé OR.
        case 0:        
        {
            unsigned char res = zxdata | 0x1F;
            //-----------------------------------------------------------------
            for (unsigned i = 0;    i < 8;    i++)
                if (!(scan & (1 << i)))
                    res &= zxkeys[i];
            //-----------------------------------------------------------------
            return res;
        }
        //---------------------------------------------------------------------
        // 1 - RD code KBD
        //     Â ýòîì ðåæèìå, íåçàâèñèìî îò ñîñòîÿíèÿ àäðåñíîé ëèíèè,
        //     êîíòðîëëåð âîçâðàùàåò CP/M êîä ïîñëåäíåé íàæàòîé êëàâèøè.
        //     Ïðè ýòîì ðåãèñòð êîíòðîëëåðà, õðàíÿùèé ýòîò êîä ñáðàñûâàåòñÿ â 0.
        case 1:
            t = kR2;
            kR2 = 0;
            return t;
        //---------------------------------------------------------------------
        // 2 - CP/M KBD
        //     Â ýòîì ðåæèìå, â çàâèñèìîñòè îò ñîñòîÿíèÿ äâóõ ñòàðøèõ áèòîâ àäðåñà ñêàíèðîâàíèÿ,
        //     êîíòðîëëåð âîçâðàùàåò:
        //         A15=0, A14=0 - CP/M êîä ïîñëåäíåé íàæàòîé êëàâèøè.
        //             Ðåãèñòð ïîñëå ÷òåíèÿ ñáðàñûâàåòñÿ.
        //         A15=0, A14=1 - ñîñòîÿíèå ðåãèñòðà óïðàâëÿþùèõ êëàâèø;
        //             d0 - Shift (1-íàæàòà)
        //             d1 - Ctrl (1-íàæàòà)
        //             d2 - ALT (1-íàæàòà)
        //             d3 - âñåãäà 0
        //             d4 - Caps Lock trigger
        //             d5 - Num Lock trigger
        //             d6 - Scroll Lock trigger
        //             d7 - RUS(1)/LAT(0)
        //         A15=1, A14=0 - ñîñòîÿíèå äîïîëíèòåëüíîãî ðåãèñòðà
        //             d0 - Right Shift
        //             d1..d7 - âñåãäà 0
        //         A15=1, A14=1 - íå íåñåò ïîëåçíîé èíôîðìàöèè
        case 2:
            switch (scan & 0xC0)
            {
                //-------------------------------------------------------------
                case 0x00:
                {
                    t = kR2;
                    kR2 = 0;
                    return t;
                }
                //-------------------------------------------------------------
                case 0x40:
                    return kR3;
                //-------------------------------------------------------------
                case 0x80:
                    return kR4;
                //-------------------------------------------------------------
                case 0xC0:
                    return kR5;
                //-------------------------------------------------------------
            }
        //---------------------------------------------------------------------
        // 3 - Direct RD
        //     Â ýòîì ðåæèìå, íåçàâèñèìî îò ñîñòîÿíèÿ àäðåñíûõ ëèíèé,
        //     êîíòðîëëåð âîçâðàùàåò ñêàí-êîä ïîñëåäíåé íàæàòîé êëàâèøè êëàâèàòóðû IBM,
        //     ïðè÷åì êîä XT-êëàâèàòóðû.
        case 3:
            t = lastscan;
            lastscan = 0;
            return t;
        //---------------------------------------------------------------------
    }
    //-------------------------------------------------------------------------
    __assume(0);
    return 0xFF;
}
//=============================================================================


//=============================================================================
void ATM_KBD::processzx(unsigned scancode, unsigned char pressed)
{
    static const unsigned char L_4B6[] =
    {
        0x39, 0x31, 0x32, 0x33, 0x34, 0x35, 0x45, 0x44,
        0x43, 0x42, 0x41, 0xE4, 0xE2, 0x49, 0x3B, 0x21,
        0x22, 0x23, 0x24, 0x25, 0x55, 0x54, 0x53, 0x52,
        0x51, 0xD5, 0xD4, 0x61, 0x88, 0x11, 0x12, 0x13,
        0x14, 0x15, 0x65, 0x64, 0x63, 0x62, 0xD2, 0xD1,
        0x91, 0x08, 0x92, 0x02, 0x03, 0x04, 0x05, 0x75,
        0x74, 0x73, 0xF4, 0xF3, 0x85, 0x80, 0xF5, 0x3C,
        0x71, 0x3A, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xC5,
        0xC4, 0xC3, 0xC2, 0xC1, 0x00, 0x00, 0x3C, 0x4C,
        0x3D, 0xE4, 0x3D, 0x35, 0x4B, 0xE3, 0x4A, 0x4D,
        0x4B, 0x84, 0x49, 0x00, 0x00, 0x00, 0xE5, 0x94,
        0x00, 0x00, 0x00
    };

    scancode = (scancode & 0xFF) - 1;
    //-------------------------------------------------------------------------
    if (scancode >= sizeof L_4B6)
        return;
    //-------------------------------------------------------------------------
    unsigned char x = L_4B6[scancode];
    if (x & 0x08)
    {
        //---------------------------------------------------------------------
        if (pressed)
        {
            zxkeys[0] &= ~1;
        }
        //---------------------------------------------------------------------
        else
        {
            zxkeys[0] |= 1;
        }
        //---------------------------------------------------------------------
    }
    //-------------------------------------------------------------------------
    if (x & 0x80)
    {
        //---------------------------------------------------------------------
        if (pressed)
        {
            zxkeys[7] &= ~2;
        }
        //---------------------------------------------------------------------
        else
        {
            zxkeys[7] |= 2;
        }
        //---------------------------------------------------------------------
    }
    //-------------------------------------------------------------------------
    if (!(x & 7))
        return;
    //-------------------------------------------------------------------------
    unsigned char data = u8(1 << ((x & 7) - 1));
    x = (x >> 4) & 7;
    //-------------------------------------------------------------------------
    if (pressed)
    {
        zxkeys[x] &= ~data;
    }
    //-------------------------------------------------------------------------
    else
    {
        zxkeys[x] |= data;
    }
    //-------------------------------------------------------------------------
}
//=============================================================================


//=============================================================================
void ATM_KBD::setkey(unsigned scancode, unsigned char pressed)
{
    //-------------------------------------------------------------------------
    if (!(mode & 3))
        processzx( scancode, pressed);
    //-------------------------------------------------------------------------
    lastscan = (unsigned char) scancode;
    //-------------------------------------------------------------------------
    if (!pressed)
    {
        lastscan |= 0x80;
        return;
    }
    //-------------------------------------------------------------------------
    kR3 &= 0x80; // keep rus/lat, clear alt,ctrl,shift, num/scroll/caps lock
    //-------------------------------------------------------------------------
    if ((kbdpc[ DIK_LSHIFT]     | kbdpc[ DIK_RSHIFT])   & 0x80) kR3 |= 1;
    if ((kbdpc[ DIK_LCONTROL]   | kbdpc[ DIK_RCONTROL]) & 0x80) kR3 |= 2;
    if ((kbdpc[ DIK_LMENU]      | kbdpc[ DIK_RMENU])    & 0x80) kR3 |= 4;
    if (kbdpc[ DIK_CAPITAL] & 1)                                        kR3 |= 0x10;
    if (kbdpc[ DIK_NUMLOCK] & 1)                                        kR3 |= 0x20;
    if (kbdpc[ DIK_SCROLL] & 1)                                 kR3 |= 0x40;
    //-------------------------------------------------------------------------
    kR4 = 0;
    if (kbdpc[ DIK_RSHIFT] & 0x80)      kR4++;
    //-------------------------------------------------------------------------
    static const unsigned char L_400[] =
    {
        0x1B, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00,
        0x38, 0x00, 0x39, 0x00, 0x30, 0x00, 0x2D, 0x00, 0x3D, 0x00, 0x08, 0x00, 0x09, 0x00, 0x51, 0x00,
        0x57, 0x00, 0x45, 0x00, 0x52, 0x00, 0x54, 0x00, 0x59, 0x00, 0x55, 0x00, 0x49, 0x00, 0x4F, 0x00,
        0x50, 0x00, 0x5B, 0x00, 0x5D, 0x00, 0x0D, 0xC0, 0x00, 0x02, 0x41, 0x00, 0x53, 0x00, 0x44, 0x00,
        0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x3B, 0x00, 0x27, 0x00,
        0x60, 0x00, 0x00, 0x03, 0x5C, 0x00, 0x5A, 0x00, 0x58, 0x00, 0x43, 0x00, 0x56, 0x00, 0x42, 0x00,
        0x4E, 0x00, 0x4D, 0x00, 0x2C, 0x00, 0x2E, 0x00, 0x2F, 0x40, 0x00, 0x03, 0xAA, 0x00, 0x00, 0x01,
        0x20, 0x00, 0x00, 0x04, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00,
        0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x37, 0x80, 0x38, 0x80,
        0x39, 0x80, 0x2D, 0x80, 0x34, 0x80, 0x35, 0x80, 0x36, 0x80, 0x2B, 0x80, 0x31, 0x80, 0x32, 0x80,
        0x33, 0x80, 0x30, 0x80, 0x2E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x6B, 0x00, 0x6C, 0x00
    };
    //-------------------------------------------------------------------------
    unsigned index = ((scancode & 0xFF) - 1) * 2;
    //-------------------------------------------------------------------------
    if (index >= sizeof(L_400))
        return;
    //-------------------------------------------------------------------------
    kR1 = kR2;
    kR2 = L_400[index];
    kR5 = L_400[index+1];
    //-------------------------------------------------------------------------
    if ((kR5 & 0x30) == 0x30)
        zxdata[0] = zxdata[1] = 0xFFFFFFFF;
    //-------------------------------------------------------------------------
    static const unsigned char L_511[] =
    {
        0x76, 0x70, 0x74, 0xAD, 0x72, 0xB5, 0x73, 0xAB, 0x77, 0x71, 0x75, 0x78, 0x79
    };
    //-------------------------------------------------------------------------
    if ((scancode & 0x100) && (kR5 & 0x40))
        kR2 |= 0x80;
    //-------------------------------------------------------------------------
    if (kR5 & 0x80)
    {
        //---------------------------------------------------------------------
        if (scancode & 0x100)
        {
            kR2 = L_511[(scancode & 0xFF) - 0x47];
        }
        //---------------------------------------------------------------------
        else
        {
            kR2 |= 0x80;
        }
        //---------------------------------------------------------------------
    }
    //-------------------------------------------------------------------------
    if (kR5 & 0x0C)
        kR5 = 0;
    //-------------------------------------------------------------------------
}
//=============================================================================


//=============================================================================
void ATM_KBD::clear()
{
    zxdata[0] = zxdata[1] = 0xFFFFFFFF;
}
//=============================================================================


//=============================================================================
void ATM_KBD::reset()
{
    kR1 = kR2 = mode = lastscan = R7 = 0;
    clear();
}
//=============================================================================