Subversion Repositories pentevo

Rev

Rev 798 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
716 lvd 1
#include "std.h"
2
 
3
#include "emul.h"
4
#include "vars.h"
5
#include "dx.h"
6
#include "tape.h"
7
#include "atm.h"
8
#include "memory.h"
9
#include "input.h"
10
#include "inputpc.h"
11
 
12
#include "util.h"
13
 
796 DimkaM 14
static unsigned char pastekeys[0x80-0x20] =
716 lvd 15
{
16
   // s     !     "     #     $     %     &     '     (     )     *     +     ,     -   .       /
17
   0x71, 0xB1, 0xD1, 0xB3, 0xB4, 0xB5, 0xC5, 0xC4, 0xC3, 0xC2, 0xF5, 0xE3, 0xF4, 0xE4, 0xF3, 0x85,
18
   // 0     1     2     3     4     5     6     7     8     9     :     ;     <     =     >     ?
19
   0x41, 0x31, 0x32, 0x33, 0x34, 0x35, 0x45, 0x44, 0x43, 0x42, 0x82, 0xD2, 0xA4, 0xE2, 0xA5, 0x84,
20
   // @     A     B     C     D     E     F     G     H     I     J     K     L     M     N     O
21
   0xB2, 0x19, 0x7D, 0x0C, 0x1B, 0x2B, 0x1C, 0x1D, 0x6D, 0x5B, 0x6C, 0x6B, 0x6A, 0x7B, 0x7C, 0x5A,
22
   // P     Q     R     S     T     U     V     W     X     Y     Z     [     \     ]     ^     _
23
   0x59, 0x29, 0x2C, 0x1A, 0x2D, 0x5C, 0x0D, 0x2A, 0x0B, 0x5D, 0x0A, 0xD5, 0x93, 0xD4, 0xE5, 0xC1,
24
   // `     a     b     c     d     e     f     g     h     i     j     k     l     m     n     o
25
   0x83, 0x11, 0x75, 0x04, 0x13, 0x23, 0x14, 0x15, 0x65, 0x53, 0x64, 0x63, 0x62, 0x73, 0x74, 0x52,
26
   // p     q     r     s     t     u     v     w     x     y     z     {     |     }     ~
27
   0x51, 0x21, 0x24, 0x12, 0x25, 0x54, 0x05, 0x22, 0x03, 0x55, 0x02, 0x94, 0x92, 0x95, 0x91, 0xC4
28
}; //`=0x83, 127=' - Alone Coder
29
 
796 DimkaM 30
static unsigned char ruspastekeys[64] =
716 lvd 31
{
32
    'A','B','W','G','D','E','V','Z','I','J','K','L','M','N','O','P',
33
    'R','S','T','U','F','H','C','^','[',']',127,'Y','X','\\',64,'Q',
34
    'a','b','w','g','d','e','v','z','i','j','k','l','m','n','o','p',
35
    'r','s','t','u','f','h','c','~','{','}','_','y','x','|','`','q'
36
}; //Alone Coder
37
 
38
void K_INPUT::clear_zx()
39
{
796 DimkaM 40
   size_t i;
716 lvd 41
   for(i = 0; i < _countof(kbd_x4); i++)
796 DimkaM 42
       kbd_x4[i] = -1U;
716 lvd 43
}
44
 
45
inline void K_INPUT::press_zx(unsigned char key)
46
{
47
   if (key & 0x08)
48
       kbd[0] &= ~1; // caps
49
   if (key & 0x80)
50
       kbd[7] &= ~2; // sym
51
   if (key & 7)
52
       kbd[(key >> 4) & 7] &= ~(1 << ((key & 7) - 1));
53
}
54
 
55
// #include "inputpc.cpp"
56
 
57
bool K_INPUT::process_pc_layout()
58
{
59
   for (unsigned i = 0; i < pc_layout_count; i++)
60
   {
61
      if (kbdpc[pc_layout[i].vkey] & 0x80)
62
      {
63
         press_zx(((kbdpc[DIK_LSHIFT] | kbdpc[DIK_RSHIFT]) & 0x80) ? pc_layout[i].shifted : pc_layout[i].normal);
64
         return true;
65
      }
66
   }
67
   return false;
68
}
69
 
70
void K_INPUT::make_matrix()
71
{
72
   unsigned char altlock = conf.input.altlock? (kbdpc[DIK_LMENU] | kbdpc[DIK_RMENU]) & 0x80 : 0;
796 DimkaM 73
   size_t i;
716 lvd 74
 
75
   kjoy = 0xFF;
796 DimkaM 76
   fjoy = 0xFF;
716 lvd 77
   switch (keymode)
78
   {
79
      case KM_DEFAULT:
80
         clear_zx();
81
         if (!altlock)
82
         {
83
            if (!conf.input.keybpcmode || !process_pc_layout())
84
            {
85
                for (i = 0; i < VK_MAX; i++)
86
                {
87
                   if (kbdpc[i] & 0x80)
88
                   {
89
                      *(inports[i].port1) &= inports[i].mask1;
90
                      *(inports[i].port2) &= inports[i].mask2;
91
/*
92
   if(kbd[6] == 0xFE)
93
       __debugbreak();
94
*/
95
                   }
96
                }
97
            }
98
         }
99
 
100
         if (conf.input.fire)
101
         {
796 DimkaM 102
             if(!--firedelay)
103
             {
104
                 firedelay = conf.input.firedelay;
105
                 firestate ^= 1;
106
             }
716 lvd 107
            zxkeymap *active_zxk = conf.input.active_zxk;
108
            if (firestate) *(active_zxk->zxk[conf.input.firenum].port) &= active_zxk->zxk[conf.input.firenum].mask;
109
         }
110
         break;
111
 
112
      case KM_KEYSTICK:
113
         for(i = 0; i < _countof(kbd_x4); i++)
114
             kbd_x4[i] = rkbd_x4[i];
796 DimkaM 115
         if(stick_delay)
116
         {
117
             stick_delay--;
118
             altlock = 1;
119
         }
120
         if(!altlock)
121
         {
122
             for(i = 0; i < VK_MAX; i++)
123
             {
124
                 if(kbdpc[i] & 0x80)
125
                 {
126
                     *(inports[i].port1) ^= ~inports[i].mask1;
127
                     *(inports[i].port2) ^= ~inports[i].mask2;
128
                 }
129
             }
130
         }
716 lvd 131
         if ((kbd_x4[0] ^ rkbd_x4[0]) | (kbd_x4[1] ^ rkbd_x4[1])) stick_delay = 10;
132
         break;
133
 
134
      case KM_PASTE_HOLD:
135
      {
136
         clear_zx();
137
         if (tdata & 0x08) kbd[0] &= ~1; // caps
138
         if (tdata & 0x80) kbd[7] &= ~2; // sym
139
         if (tdata & 7) kbd[(tdata >> 4) & 7] &= ~(1 << ((tdata & 7) - 1));
140
         if (tdelay) { tdelay--; break; }
141
         tdelay = conf.input.paste_release;
142
         if (tdata == 0x61) tdelay += conf.input.paste_newline;
143
         keymode = KM_PASTE_RELEASE;
144
         break;
145
      }
146
 
147
      case KM_PASTE_RELEASE:
148
      {
149
         clear_zx();
150
         if (tdelay) { tdelay--; break; }
151
         if (textsize == textoffset)
152
         {
153
            keymode = KM_DEFAULT;
154
            free(textbuffer);
796 DimkaM 155
            textbuffer = nullptr;
716 lvd 156
            break;
157
         }
158
         tdelay = conf.input.paste_hold;
159
         unsigned char kdata = textbuffer[textoffset++];
160
         if (kdata == 0x0D)
161
         {
162
            if (textoffset < textsize && textbuffer[textoffset] == 0x0A) textoffset++;
163
            tdata = 0x61;
164
         }
165
         else
166
         {
167
            if (kdata == 0xA8) kdata = 'E'; //Alone Coder (big YO)
168
            if ((kdata >= 0xC0)||(kdata == 0xB8)) //RUS
169
            {
170
                //pressedit=
171
                //0 = press edit, pressedit++, textoffset--
172
                //1 = press letter, pressedit++, textoffset--
173
                //2 = press edit, pressedit=0
174
                switch (pressedit)
175
                {
176
                    case 0:
177
                    {
178
                        tdata = 0x39;
179
                        pressedit++;
180
                        textoffset--;
181
                        break;
182
                    };
183
                    case 1:
184
                    {
185
                        if (kdata == 0xB8) kdata = '&';else kdata = ruspastekeys[kdata - 0xC0];
186
                        tdata = pastekeys[kdata - 0x20];
187
                        pressedit++;
188
                        textoffset--;
189
                        break;
190
                    }
191
                    case 2:
192
                    {
193
                        tdata = 0x39;
194
                        pressedit = 0;
195
                    };
196
                };
197
                if (!tdata)
198
                    break; // empty key
199
            } //Alone Coder
200
            else
201
            {
202
                if (kdata < 0x20 || kdata >= 0x80) break; // keep release state
203
                tdata = pastekeys[kdata - 0x20];
204
                if (!tdata) break; // empty key
205
            }
206
         }
207
         keymode = KM_PASTE_HOLD;
208
         break;
209
      }
210
   }
211
   kjoy ^= 0xFF;
212
   if (conf.input.joymouse)
213
       kjoy |= mousejoy;
214
 
215
   for(i = 0; i < _countof(kbd_x4); i++)
216
       rkbd_x4[i] = kbd_x4[i];
217
   if (!conf.input.keymatrix)
218
       return;
219
   for (;;)
220
   {
221
      char done = 1;
796 DimkaM 222
      for (size_t k = 0; k < _countof(kbd) - 1; k++)
716 lvd 223
      {
796 DimkaM 224
         for (size_t j = k+1; j < _countof(kbd); j++)
716 lvd 225
         {
226
            if (((kbd[k] | kbd[j]) != 0xFF) && (kbd[k] != kbd[j]))
227
            {
228
               kbd[k] = kbd[j] = (kbd[k] & kbd[j]);
229
               done = 0;
230
            }
231
         }
232
      }
233
      if (done)
234
          return;
235
   }
236
}
237
 
238
__inline int sign_pm(int a) { return (a < 0)? -1 : 1; }
239
 
800 DimkaM 240
static u8 CapsLockState = 0;
241
 
716 lvd 242
char K_INPUT::readdevices()
243
{
244
   if (nomouse) nomouse--;
245
 
246
   kbdpc[VK_JLEFT] = kbdpc[VK_JRIGHT] = kbdpc[VK_JUP] = kbdpc[VK_JDOWN] = kbdpc[VK_JFIRE] = 0;
247
   int i;
248
   for(i = 0; i < 32; i++)
249
       kbdpc[VK_JB0 + i] = 0;
250
   if (active && dijoyst)
251
   {
252
      dijoyst->Poll();
253
      DIJOYSTATE js;
254
      readdevice(&js, sizeof js, (LPDIRECTINPUTDEVICE)dijoyst);
255
      if ((signed short)js.lX < 0) kbdpc[VK_JLEFT] = 0x80;
256
      if ((signed short)js.lX > 0) kbdpc[VK_JRIGHT] = 0x80;
257
      if ((signed short)js.lY < 0) kbdpc[VK_JUP] = 0x80;
258
      if ((signed short)js.lY > 0) kbdpc[VK_JDOWN] = 0x80;
259
 
260
      for(i = 0; i < 32; i++)
261
      {
262
          if (js.rgbButtons[i] & 0x80)
263
              kbdpc[VK_JB0 + i] = 0x80;
264
      }
265
   }
266
 
267
   mbuttons = 0xFF;
796 DimkaM 268
   msx_prev = msx; msy_prev = msy;
716 lvd 269
   kbdpc[VK_LMB] = kbdpc[VK_RMB] = kbdpc[VK_MMB] = kbdpc[VK_MWU] = kbdpc[VK_MWD] = 0;
270
   if ((conf.fullscr || conf.lockmouse) && !nomouse)
271
   {
272
      unsigned cl1, cl2;
796 DimkaM 273
      cl1 = unsigned(abs(msx - msx_prev)) * ay_reset_t / conf.frame;
274
      cl2 = unsigned(abs(msx - msx_prev));
275
      ay_x0 += int(cl2-cl1)*sign_pm(msx - msx_prev);
276
      cl1 = unsigned(abs(msy - msy_prev)) * ay_reset_t / conf.frame;
277
      cl2 = unsigned(abs(msy - msy_prev));
278
      ay_y0 += int(cl2-cl1)*sign_pm(msy - msy_prev);
716 lvd 279
      ay_reset_t = 0;
280
 
281
//      printf("%s\n", __FUNCTION__);
282
      DIMOUSESTATE md;
283
      readmouse(&md);
284
      if (conf.input.mouseswap)
285
      {
286
          unsigned char t = md.rgbButtons[0];
287
          md.rgbButtons[0] = md.rgbButtons[1];
288
          md.rgbButtons[1] = t;
289
      }
290
      msx = md.lX; msy = -md.lY;
291
      if (conf.input.mousescale >= 0)
292
      {
293
          msx *= (1 << conf.input.mousescale);
294
          msy *= (1 << conf.input.mousescale);
295
      }
296
      else
297
      {
298
          msx /= (1 << -conf.input.mousescale);
299
          msy /= (1 << -conf.input.mousescale);
300
      }
301
 
302
      if (md.rgbButtons[0])
303
      {
304
          mbuttons &= ~1;
305
          kbdpc[VK_LMB] = 0x80;
306
      }
307
      if (md.rgbButtons[1])
308
      {
309
          mbuttons &= ~2;
310
          kbdpc[VK_RMB] = 0x80;
311
      }
312
      if (md.rgbButtons[2])
313
      {
314
          mbuttons &= ~4;
315
          kbdpc[VK_MMB] = 0x80;
316
      }
317
 
318
      int wheel_delta = md.lZ - prev_wheel;
319
      prev_wheel = md.lZ;
320
//      if (wheel_delta < 0) kbdpc[VK_MWD] = 0x80;
321
//      if (wheel_delta > 0) kbdpc[VK_MWU] = 0x80;
322
//0.36.6 from 0.35b2
323
      if (conf.input.mousewheel == MOUSE_WHEEL_KEYBOARD)
324
      {
325
         if (wheel_delta < 0)
326
             kbdpc[VK_MWD] = 0x80;
327
         if (wheel_delta > 0)
328
             kbdpc[VK_MWU] = 0x80;
329
      }
330
 
331
      if (conf.input.mousewheel == MOUSE_WHEEL_KEMPSTON)
332
      {
333
         if (wheel_delta < 0)
334
             wheel -= 0x10;
335
         if (wheel_delta > 0)
336
             wheel += 0x10;
337
         mbuttons = (mbuttons & 0x0F) + (wheel & 0xF0);
338
      }
339
//~
340
   }
341
 
342
   lastkey = process_msgs();
343
 
800 DimkaM 344
   memset(kbdpc, 0, 256); // ���� � �������� �� �������
716 lvd 345
   ReadKeyboard(kbdpc);
800 DimkaM 346
 
347
   // ����������� "���������" CapsLock, CapsLock ��� ����������� ������� ���������� ������ 0x80, ���� �� ����� ����� ��������
348
   u8 cl = kbdpc[DIK_CAPSLOCK];
349
   kbdpc[DIK_CAPSLOCK] ^= CapsLockState;
350
   CapsLockState = cl;
351
 
716 lvd 352
/* [vv]
353
   if (temp.win9x)
354
   {
355
      kbdpc[VK_LSHIFT]=kbdpcEX[0];
356
      kbdpc[VK_RSHIFT]=kbdpcEX[1];
357
      kbdpc[VK_LCONTROL]=kbdpcEX[2];
358
      kbdpc[VK_RCONTROL]=kbdpcEX[3];
359
      kbdpc[VK_LMENU]=kbdpcEX[4];
360
      kbdpc[VK_RMENU]=kbdpcEX[5];
361
   } //Dexus
362
*/
363
 
364
   return lastkey ? 1 : 0;
365
}
366
 
367
void K_INPUT::aymouse_wr(unsigned char val)
368
{
796 DimkaM 369
    // reset by edge bit6: 1->0
370
    if(ayR14 & ~val & 0x40)
371
    {
372
        ay_x0 = ay_y0 = 8;
373
        ay_reset_t = cpu.t;
374
    }
375
    ayR14 = val;
716 lvd 376
}
377
 
378
unsigned char K_INPUT::aymouse_rd()
379
{
380
   unsigned coord;
381
   if (ayR14 & 0x40) {
796 DimkaM 382
      unsigned cl1 = unsigned(abs(msy - msy_prev)) * ay_reset_t / conf.frame;
383
      unsigned cl2 = unsigned(abs(msy - msy_prev)) * cpu.t / conf.frame;
384
      coord = unsigned(ay_y0 + int(cl2-cl1)*sign_pm(msy - msy_prev));
716 lvd 385
   } else {
796 DimkaM 386
      unsigned cl1 = unsigned(abs(msx - msx_prev)) * ay_reset_t / conf.frame;
387
      unsigned cl2 = unsigned(abs(msx - msx_prev)) * cpu.t / conf.frame;
388
      coord = unsigned(ay_x0 + int(cl2-cl1)*sign_pm(msx - msx_prev));
716 lvd 389
   }
390
/*
391
   int coord = (ayR14 & 0x40)?
392
     ay_y0 + 0x100 * (msy - msy_prev) * (int)(cpu.t - ay_reset_t) / (int)conf.frame:
393
     ay_x0 + 0x100 * (msx - msx_prev) * (int)(cpu.t - ay_reset_t) / (int)conf.frame;
394
//   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);
395
*/
796 DimkaM 396
   return 0xC0 | (coord & 0x0F) | u8(mbuttons << 4);
716 lvd 397
}
398
 
399
unsigned char K_INPUT::kempston_mx()
400
{
796 DimkaM 401
   int x = (int(cpu.t)*msx + int(conf.frame - cpu.t)*msx_prev) / int(conf.frame);
716 lvd 402
   return (unsigned char)x;
403
}
404
 
405
unsigned char K_INPUT::kempston_my()
406
{
796 DimkaM 407
   int y = (int(cpu.t)*msy + int(conf.frame - cpu.t)*msy_prev) / int(conf.frame);
716 lvd 408
   return (unsigned char)y;
409
}
410
 
411
unsigned char K_INPUT::read(unsigned char scan)
412
{
413
   unsigned char res = 0xBF | (tape_bit() & 0x40);
414
   kbdled &= scan;
415
 
416
   if (conf.atm.xt_kbd)
417
       return input.atm51.read(scan, res);
418
 
419
   for (int i = 0; i < 8; i++)
420
   {
421
      if (!(scan & (1<<i)))
422
          res &= kbd[i];
423
   }
424
 
425
/*
426
   if(res != 0xFF)
427
       __debugbreak();
428
*/
429
 
430
   return res;
431
}
432
 
433
// read quorum additional keys (port 7E)
434
u8 K_INPUT::read_quorum(u8 scan)
435
{
436
   u8 res = 0xFF;
437
   kbdled &= scan;
438
 
439
   for (int i = 0; i < 8; i++)
440
   {
441
      if (!(scan & (1<<i)))
442
          res &= kbd[8+i];
443
   }
444
 
445
   return res;
446
}
447
 
448
void K_INPUT::paste()
449
{
796 DimkaM 450
   free(textbuffer); textbuffer = nullptr;
716 lvd 451
   textsize = textoffset = 0;
452
   keymode = KM_DEFAULT;
453
   if (!OpenClipboard(wnd)) return;
454
   HANDLE hClip = GetClipboardData(CF_TEXT);
455
   if (hClip) {
456
      void *ptr = GlobalLock(hClip);
457
      if (ptr) {
458
         keymode = KM_PASTE_RELEASE; tdelay = 1;
796 DimkaM 459
         textsize = unsigned(strlen((char*)ptr) + 1);
716 lvd 460
         memcpy(textbuffer = (unsigned char*)malloc(textsize), ptr, textsize);
461
         GlobalUnlock(hClip);
462
      }
463
   }
464
   CloseClipboard();
465
}
466
 
467
unsigned char ATM_KBD::read(unsigned char scan, unsigned char zxdata)
468
{
469
   unsigned char t;
470
 
471
   if (R7) {
472
      if (R7 == 1) cmd = scan;
473
      switch (cmd & 0x3F) {
474
         case 1:
475
         {
476
            static const unsigned char ver[4] = { 6,0,1,0 };
477
            R7 = 0; return ver[cmd >> 6];
478
         }
479
         case 7: clear(); R7 = 0; return 0xFF; // clear data buffer in mode0
480
         case 8:
481
            if (R7 == 2) { mode = scan; kR2 = 0; R7 = 0; return 0xFF; }
482
            R7++; return 8;
483
         case 9:
484
            switch (cmd & 0xC0) {
485
               case 0x00: t = kR1;
486
               case 0x40: t = kR2;
487
               case 0x80: t = kR3;
488
               case 0xC0: t = kR4;
489
            }
490
            R7 = 0;
491
            return t;
492
         case 10:
493
            kR3 |= 0x80; R7 = 0; return 0xFF;
494
         case 11:
495
            kR3 &= 0x7F; R7 = 0; return 0xFF;
496
//         case 12: R7 = 0; return 0xFF; // enter pause mode
497
         case 13:
498
            // reset!
499
            this->reset();
500
            cpu.int_flags = cpu.ir_ = cpu.pc = 0; cpu.im = 0;
501
            comp.p7FFD = comp.flags = 0;
502
            set_atm_FF77(0,0);
503
            set_banks();
504
            break;
505
         case 16:
506
         case 18:
507
         {
508
            SYSTEMTIME time; GetLocalTime(&time);
509
            R7 = 0;
510
            if (cmd == 0x10) return (BYTE)time.wSecond;
511
            if (cmd == 0x40) return (BYTE)time.wMinute;
512
            if (cmd == 0x80) return (BYTE)time.wHour;
513
            if (cmd == 0xC0) return (BYTE)time.wDay;
514
            if (cmd == 0x12) return (BYTE)time.wDay;
515
            if (cmd == 0x42) return (BYTE)time.wMonth;
516
            if (cmd == 0x82) return (BYTE)(time.wYear % 100);
517
            if (cmd == 0xC2) return (BYTE)(time.wYear / 100);
518
         }
519
         case 17: // set time
520
         case 19: // set date
521
            if (R7 == 2) R7 = 0; else R7++;
522
            return 0xFF;
523
      }
524
      R7 = 0;
525
      return 0xFF;
526
   }
527
 
528
   if (scan == 0x55) { R7++; return 0xAA; }
529
 
530
   switch (mode & 3)
531
   {
532
      case 0:
533
      {
534
         unsigned char res = zxdata | 0x1F;
535
         for (unsigned i = 0; i < 8; i++)
536
            if (!(scan & (1 << i))) res &= zxkeys[i];
537
         return res;
538
      }
539
      case 1: t = kR2; kR2 = 0; return t;
540
      case 2:
541
         switch (scan & 0xC0)
542
         {
543
            case 0x00: { t = kR2; kR2 = 0; return t; }
544
            case 0x40: return kR3;
545
            case 0x80: return kR4;
546
            case 0xC0: return kR5;
547
         }
548
      case 3: t = lastscan; lastscan = 0; return t;
549
   }
550
   __assume(0);
551
   return 0xFF;
552
}
553
 
554
void ATM_KBD::processzx(unsigned scancode, unsigned char pressed)
555
{
556
   static const unsigned char L_4B6[] =
557
   {
558
      0x39, 0x31, 0x32, 0x33, 0x34, 0x35, 0x45, 0x44,
559
      0x43, 0x42, 0x41, 0xE4, 0xE2, 0x49, 0x3B, 0x21,
560
      0x22, 0x23, 0x24, 0x25, 0x55, 0x54, 0x53, 0x52,
561
      0x51, 0xD5, 0xD4, 0x61, 0x88, 0x11, 0x12, 0x13,
562
      0x14, 0x15, 0x65, 0x64, 0x63, 0x62, 0xD2, 0xD1,
563
      0x91, 0x08, 0x92, 0x02, 0x03, 0x04, 0x05, 0x75,
564
      0x74, 0x73, 0xF4, 0xF3, 0x85, 0x80, 0xF5, 0x3C,
565
      0x71, 0x3A, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xC5,
566
      0xC4, 0xC3, 0xC2, 0xC1, 0x00, 0x00, 0x3C, 0x4C,
567
      0x3D, 0xE4, 0x3D, 0x35, 0x4B, 0xE3, 0x4A, 0x4D,
568
      0x4B, 0x84, 0x49, 0x00, 0x00, 0x00, 0xE5, 0x94,
569
      0x00, 0x00, 0x00
570
   };
571
 
572
   scancode = (scancode & 0xFF) - 1;
573
   if (scancode >= sizeof L_4B6)
574
       return;
575
 
576
   unsigned char x = L_4B6[scancode];
577
   if (x & 0x08) { if (pressed) zxkeys[0] &= ~1; else zxkeys[0] |= 1; }
578
   if (x & 0x80) { if (pressed) zxkeys[7] &= ~2; else zxkeys[7] |= 2; }
579
 
580
   if (!(x & 7))
581
       return;
582
 
796 DimkaM 583
   unsigned char data = u8(1 << ((x & 7) - 1));
716 lvd 584
   x = (x >> 4) & 7;
585
 
586
   if (pressed)
587
       zxkeys[x] &= ~data;
588
   else
589
       zxkeys[x] |= data;
590
}
591
 
592
void ATM_KBD::setkey(unsigned scancode, unsigned char pressed)
593
{
594
   if (!(mode & 3)) processzx(scancode, pressed);
595
   lastscan = (unsigned char)scancode;
596
   if (!pressed) { lastscan |= 0x80; return; }
597
 
598
   kR3 &= 0x80; // keep rus/lat, clear alt,ctrl,shift, num/scroll/caps lock
599
   if ((kbdpc[DIK_LSHIFT] | kbdpc[DIK_RSHIFT]) & 0x80) kR3 |= 1;
600
   if ((kbdpc[DIK_LCONTROL] | kbdpc[DIK_RCONTROL]) & 0x80) kR3 |= 2;
601
   if ((kbdpc[DIK_LMENU] | kbdpc[DIK_RMENU]) & 0x80) kR3 |= 4;
602
   if (kbdpc[DIK_CAPITAL] & 1) kR3 |= 0x10;
603
   if (kbdpc[DIK_NUMLOCK] & 1) kR3 |= 0x20;
604
   if (kbdpc[DIK_SCROLL] & 1) kR3 |= 0x40;
605
   kR4 = 0; if (kbdpc[DIK_RSHIFT] & 0x80) kR4++;
606
 
607
   static const unsigned char L_400[] =
608
   {
609
      0x1B, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00,
610
      0x38, 0x00, 0x39, 0x00, 0x30, 0x00, 0x2D, 0x00, 0x3D, 0x00, 0x08, 0x00, 0x09, 0x00, 0x51, 0x00,
611
      0x57, 0x00, 0x45, 0x00, 0x52, 0x00, 0x54, 0x00, 0x59, 0x00, 0x55, 0x00, 0x49, 0x00, 0x4F, 0x00,
612
      0x50, 0x00, 0x5B, 0x00, 0x5D, 0x00, 0x0D, 0xC0, 0x00, 0x02, 0x41, 0x00, 0x53, 0x00, 0x44, 0x00,
613
      0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x3B, 0x00, 0x27, 0x00,
614
      0x60, 0x00, 0x00, 0x03, 0x5C, 0x00, 0x5A, 0x00, 0x58, 0x00, 0x43, 0x00, 0x56, 0x00, 0x42, 0x00,
615
      0x4E, 0x00, 0x4D, 0x00, 0x2C, 0x00, 0x2E, 0x00, 0x2F, 0x40, 0x00, 0x03, 0xAA, 0x00, 0x00, 0x01,
616
      0x20, 0x00, 0x00, 0x04, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x00,
617
      0x67, 0x00, 0x68, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x00, 0x08, 0x00, 0x0C, 0x37, 0x80, 0x38, 0x80,
618
      0x39, 0x80, 0x2D, 0x80, 0x34, 0x80, 0x35, 0x80, 0x36, 0x80, 0x2B, 0x80, 0x31, 0x80, 0x32, 0x80,
619
      0x33, 0x80, 0x30, 0x80, 0x2E, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x6B, 0x00, 0x6C, 0x00
620
   };
621
   unsigned index = ((scancode & 0xFF) - 1)*2;
622
   if (index >= sizeof(L_400)) return;
623
   kR1 = kR2; kR2 = L_400[index];
624
   kR5 = L_400[index+1];
625
 
626
   if ((kR5 & 0x30) == 0x30) zxdata[0] = zxdata[1] = 0xFFFFFFFF;
627
   static const unsigned char L_511[] = { 0x76, 0x70, 0x74, 0xAD, 0x72, 0xB5, 0x73, 0xAB, 0x77, 0x71, 0x75, 0x78, 0x79 };
628
   if ((scancode & 0x100) && (kR5 & 0x40)) kR2 |= 0x80;
629
   if (kR5 & 0x80) {
630
      if (scancode & 0x100) kR2 = L_511[(scancode & 0xFF) - 0x47];
631
      else kR2 |= 0x80;
632
   }
633
   if (kR5 & 0x0C) kR5 = 0;
634
}
635
 
636
void ATM_KBD::clear()
637
{
638
   zxdata[0] = zxdata[1] = 0xFFFFFFFF;
639
}
640
 
641
void ATM_KBD::reset()
642
{
643
   kR1 = kR2 = mode = lastscan = R7 = 0;
644
   clear();
645
}