Subversion Repositories pentevo

Rev

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