; Text CodePage = cp1251 ; Предварительно необходимо установить режим ввода сканкодов ;set_ckancode_mode: ; xor ecx, ecx ; inc ecx ; mcall 66,1 ; установка режима ввода сканкодов ; ret ;----------------------------------------------------- load_port_FE: ; дешифровка пора FE - клавиатура Spectruma ; вход ax - номер порта al = 0xFE ah = [старший байт адреса порта] ; выход - al - содержимое порта клавиатуры остальные байты произвольны ; производится полная дешифрация порта c произвольными значениями ; старшего байта (как в настоящем спекке) cmp al, 0xFE jne .ret push esi push ebx mov esi, zx_keys ; будем вычитывать из буфера клавы mov bl, 0xFF cld rept 8 { lodsb shr ah, 1 jc @f and bl, al @@: } mov al, bl pop ebx pop esi .ret: ret ;------------------------------------------------------ ; Чтение клавиатуры PC и перевод ее состояния в буфер порта FE спектрума load_keys: ; регистры не сохраняет mov edi, scancodes_tbl ; Адрес таблицы обработки сканкодов mov ebx, 0xFFFFFFE0 ; вспомогательная маска mov edx, dword [zx_keys] ; буфер клавиатуры спектрума mov esi, dword [zx_keys+4] ; .loop: ; цикл выбора клавиш из буфера mov ecx, ebx ; сохранить ebx mcall 66,3 ; проверить управляющие клавиши mov ebx, ecx ; восстановить ebx and al, 0x80 ; проверить NumLock mov byte [num_lock_flag], al .loop_1: mcall 2 ; забрать код нажатой клавиши cmp eax, 1 jne .load ; если буфер не пуст .exit: mov dword [zx_keys], edx mov dword [zx_keys+4], esi .ret: ret .ext_key: mov byte [ext_flag], 1 jmp .loop .load: cmp ah, 250 jne @f or edx, 0x02000001 ; стираем CAPS LOCK {, NumLock, ScrollLock - ?} ; or esi, 0x00000000 mov byte [ ext_flag], 0 jmp .loop_1 @@: cmp ah, 224 je .ext_key ; если расширенная клавиша mov cl, ah and cl, 0x7F cmp cl, 71 ; если клавиши из NumPad jc .l1 cmp cl, 84 jnc .l1 cmp byte [ ext_flag], 1 ; если клавиша нажата после EXT je .l1 ; если клавиша без ext - cmp byte [num_lock_flag], 0 ; если установлен режим курсора jne .lnorm ; дополнительное извращение для ввода цифр на NumPade sub cl, 71 and eax, 0x00008000 mov al, cl jz .l1_2 xor ah, ah jz ._1_2 .l1: mov byte [ext_flag], 0 .lnorm: mov al, ah ; scancode в al and eax, 0x000000FF ;отрезание старшей части от al or al, al js ._1 ; Если выдан сканкод нажатия клавиши .l1_1: add al, 13 .l1_2: shl eax, 1 ; *2 mov ax, word [ edi+eax] ; al - 1 клав , ah - 2 клав mov ecx, eax call .L_proc_set ; 1 - клавиша shr ecx, 8 mov eax, ecx call .L_proc_set ; 2 - клавиша jmp .loop_1 ; продолжить выбор из буфера ._1: ;Если выдан сканкод отпускания клавиши and al, 0x7f add al, 13 ._1_2: shl eax, 1 ; *2 mov ax, word [ edi+eax] ; al - 1 клав , ah - 2 клав mov ecx, eax call .L_proc_res ; 1 - клавиша shr ecx, 8 mov eax, ecx call .L_proc_res ; 2 - клавиша jmp .loop_1 .L_proc_set: or cl, cl jz .ret or eax, ebx and cl, bl ; маска порта *32 or cl, cl js @f ; порт расположен в edx ror cl, 2 ; циклическое смещение rol eax, cl and edx, eax ; сохранение клавиши ret @@: ; порт расположен в esi and cl, 0x60 ; нормировка маски ror cl, 2 rol eax, cl and esi, eax ret .L_proc_res: or cl, cl jz .ret or eax, ebx xor eax, -1 and cl, bl ; маска порта *32 or cl, cl js @f ; порт расположен в edx ror cl, 2 ; циклическое смещение rol eax, cl or edx, eax ; удаление клавиши ret @@: ; порт расположен в esi and cl, 0x60 ; нормировка маски ror cl, 2 rol eax, cl or esi, eax ret ;-------------------------------------------------------- ; Клавиатура для Спектрума ;----------------------------------------------------- ; SHIFT - CAPS SHIFT (CS) ; CTRL - SIMBOL SHIFT (SS) ; ALT - EXTEND MODE (CS/SS) ; Обычным способом CS/SS не набирается ; ; BACKSPACE - DELETE (CS/0) ; ESC - BREAK (CS/Space) ; TAB - EDIT (CS/1) ; '~' - GRAPH (CS/9) ; PAGE UP - TRUE VIDEO (CS/3) ; PAGE DOWN - INV. VIDEO (CS/4) ; UP - UP (CS/7) ; DOWN - DOWN (CS/6) ; LEFT - LEFT (CS/5) ; RIGHT - RIGHT (CS/8) ; CAPS LOCK - /CAPS LOCK/ - не работает набирать только как (CS/2) not_used_code equ 0x1F1F ; код для неиспользуемого сканкода ; код сканкода - 0x[байт префикса][байт клавиши] ; [байт клавиши / префикса] - биты=PPPKKKKK ; где PPP - код порта ; KKKKK - код клавиши ; таблица соответствия сканкодов кодам обработки клавиш - 256 - байт scancodes_tbl dw 0x0097 ; 71 - Num7 dw 0x009B ; 72 - Num8 dw 0x009D ; 73 - Num9 dw 0xFDD7 ; 74 - Num- dw 0x0077 ; 75 - Num4 dw 0x006F ; 76 - Num5 dw 0x008F ; 77 - Num6 dw 0xFDDB ; 78 - Num+ dw 0x007E ; 79 - Num1 dw 0x007D ; 80 - Num2 dw 0x007B ; 81 - Num3 dw 0x009E ; 82 - Num0 dw 0xFDFB ; 83 - Num. dw not_used_code ; 0 ; ------------------------------------------- dw 0x1EFE ; 1 - ESC - Break (CS/Space) dw 0x007E ; 2 - 1 dw 0x007D ; 3 - 2 dw 0x007B ; 4 - 3 dw 0x0077 ; 5 - 4 dw 0x006F ; 6 - 5 dw 0x008F ; 7 - 6 dw 0x0097 ; 8 - 7 dw 0x009B ; 9 - 8 dw 0x009D ; 10 - 9 dw 0x009E ; 11 - 0 dw 0xFDD7 ; 12 - - dw 0xFDDD ; 13 - = dw 0x1E9E ; 14 - BackSpace - Delete(backspace) (CS/0) dw 0x1E7E ; 15 - TAB - EDIT (CS/1) dw 0x005E ; 16 - q dw 0x005D ; 17 - w dw 0x005B ; 18 - e dw 0x0057 ; 19 - r dw 0x004F ; 20 - t dw 0x00AF ; 21 - y dw 0x00B7 ; 22 - u dw 0x00BB ; 23 - i dw 0x00BD ; 24 - o dw 0x00BE ; 25 - p dw 0xFDAF ; 26 - [ - SS/Y dw 0xFDB7 ; 27 - ] - SS/U dw 0x00DE ; 28 - Enter dw 0x00FD ; 29 - L_Control - Simbol Shift (SS) dw 0x003E ; 30 - a dw 0x003D ; 31 - s dw 0x003B ; 32 - d dw 0x0037 ; 33 - f dw 0x002F ; 34 - g dw 0x00CF ; 35 - h dw 0x00D7 ; 36 - j dw 0x00DB ; 37 - k dw 0x00DD ; 38 - l dw 0xFDBD ; 39 - ; - ; (SS/O) dw 0xFD97 ; 40 - ' - ' (SS/7) dw 0x1E9D ; 41 - ~ - GRAPH (CS/9) dw 0x001E ; 42 - L_Shift (эм caps ) dw 0xFD3B ; 43 - \ - SS/D dw 0x001D ; 44 - z dw 0x001B ; 45 - x dw 0x0017 ; 46 - c dw 0x000F ; 47 - v dw 0x00EF ; 48 - b dw 0x00F7 ; 49 - n dw 0x00FB ; 50 - m dw 0xFDF7 ; 51 - , dw 0xFDFB ; 52 - . dw 0xFD0F ; 53 - / dw 0x001E ; 54 - R_Shift - CAPS (CS) dw 0xFDEF ; 55 - Num * - * (SS/B) dw 0xFD1E ; 56 - ALT - Extend Mode (CS/SS) dw 0x00FE ; 57 - Space dw 0x1E7D ; 58 - Caps Lock - Caps Lock (CS/2) dw not_used_code ; 59 - F1 dw not_used_code ; 60 - F2 dw not_used_code ; 61 - F3 dw not_used_code ; 62 - F4 dw not_used_code ; 63 - F5 dw not_used_code ; 64 - F6 dw not_used_code ; 65 - F7 dw not_used_code ; 66 - F8 dw not_used_code ; 67 - F9 dw not_used_code ; 68 - F10 dw not_used_code ; 69 - NumLock (отпуск M 250) ; BREAK совместно (225,29,69) (225 - EXT2) (29 -L_Control) dw not_used_code ; 70 - Scroll Lock ( отпуск М 250) dw not_used_code ; 71 - Home (после EXT) (ем dw 0x1E97 ; 72 - Up (после EXT) - UP (CS/7) dw 0x1E7B ; 73 - Page Up (после EXT - 224) - True video (CS/3) dw 0xFDD7 ; 74 - Num- - - (SS/J) dw 0x1E6F ; 75 - Left (после EXT) - <-- (CS/5) dw not_used_code ; 76 - Num5 dw 0x1E9B ; 77 - Right (после EXT) - --> (CS/8) dw 0xFDDB ; 78 - Num+ dw not_used_code ; 79 - END (после EXT) dw 0x1E8F ; 80 - Down (после EXT) - DOWN (CS/6) dw 0x1E77 ; 81 - Page Down (после EXT) - Inv. Video (CS/4) dw not_used_code ; 82 - Insert (после EXT) dw not_used_code ; 83 - Delete (после EXT) dw not_used_code ; 84 dw not_used_code ; 85 dw not_used_code ; 86 dw not_used_code ; 87 - F11 dw not_used_code ; 88 - F12 dw not_used_code ; 89 dw not_used_code ; 90 dw not_used_code ; 91 dw not_used_code ; 92 dw not_used_code ; 93 - Меню 3 (после ext) dw not_used_code ; 94 dw not_used_code ; 95 dw not_used_code ; 96 - (224) - ext - доп. функция сканкодов dw not_used_code ; 97 - (225) - ext2 dw not_used_code ; 98 dw not_used_code ; 99 dw not_used_code ; 100 dw not_used_code ; 101 dw not_used_code ; 102 dw not_used_code ; 103 dw not_used_code ; 104 dw not_used_code ; 105 dw not_used_code ; 106 dw not_used_code ; 107 dw not_used_code ; 108 dw not_used_code ; 109 dw not_used_code ; 110 dw not_used_code ; 111 dw not_used_code ; 112 dw not_used_code ; 113 dw not_used_code ; 114 dw not_used_code ; 115 dw not_used_code ; 116 dw not_used_code ; 117 dw not_used_code ; 118 dw not_used_code ; 119 dw not_used_code ; 120 dw not_used_code ; 121 dw not_used_code ; 122 - (250) M Отпуск (Capslock, Numlock и т.п.) dw not_used_code ; 123 dw not_used_code ; 124 dw not_used_code ; 125 dw not_used_code ; 126 dw not_used_code ; 127 dw 0 ; Флаги клавиатуры ext_flag db 0 ; флаг расширенного сканкода num_lock_flag db 0 ; флаг num клавы ;Буфер ZX-Spectrum клавиатуры. zx_keys dd 0xFFFFFFFF, 0xFFFFFFFF ;позиция байта/старший байт порта: ; +0 - FE ; +1 - FD ; +2 - FB ; +3 - F7 ; +4 - EF ; +5 - DF ; +6 - BF ; +7 - 7F