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 | } |