Преобразование кода AT&T в XT
1module PS2ATXT
2(
3    input wire       clock50,
4    input wire [7:0] ps2_data,
5    output reg [7:0] keyb_xt,
6    output reg [7:0] scancode
7);
8
9always @(*) begin
10
11    case (ps2_data)
12
13        /* A   */ 8'h1C: keyb_xt = 8'h1E;
14        /* B   */ 8'h32: keyb_xt = 8'h30;
15        /* C   */ 8'h21: keyb_xt = 8'h2E;
16        /* D   */ 8'h23: keyb_xt = 8'h20;
17        /* E   */ 8'h24: keyb_xt = 8'h12;
18        /* F   */ 8'h2B: keyb_xt = 8'h21;
19        /* G   */ 8'h34: keyb_xt = 8'h22;
20        /* H   */ 8'h33: keyb_xt = 8'h23;
21        /* I   */ 8'h43: keyb_xt = 8'h17;
22        /* J   */ 8'h3B: keyb_xt = 8'h24;
23        /* K   */ 8'h42: keyb_xt = 8'h25;
24        /* L   */ 8'h4B: keyb_xt = 8'h26;
25        /* M   */ 8'h3A: keyb_xt = 8'h32;
26        /* N   */ 8'h31: keyb_xt = 8'h31;
27        /* O   */ 8'h44: keyb_xt = 8'h18;
28        /* P   */ 8'h4D: keyb_xt = 8'h19;
29        /* Q   */ 8'h15: keyb_xt = 8'h10;
30        /* R   */ 8'h2D: keyb_xt = 8'h13;
31        /* S   */ 8'h1B: keyb_xt = 8'h1F;
32        /* T   */ 8'h2C: keyb_xt = 8'h14;
33        /* U   */ 8'h3C: keyb_xt = 8'h16;
34        /* V   */ 8'h2A: keyb_xt = 8'h2F;
35        /* W   */ 8'h1D: keyb_xt = 8'h11;
36        /* X   */ 8'h22: keyb_xt = 8'h2D;
37        /* Y   */ 8'h35: keyb_xt = 8'h15;
38        /* Z   */ 8'h1A: keyb_xt = 8'h2C;
39        /* 0   */ 8'h45: keyb_xt = 8'h0B;
40        /* 1   */ 8'h16: keyb_xt = 8'h02;
41        /* 2   */ 8'h1E: keyb_xt = 8'h03;
42        /* 3   */ 8'h26: keyb_xt = 8'h04;
43        /* 4   */ 8'h25: keyb_xt = 8'h05;
44        /* 5   */ 8'h2E: keyb_xt = 8'h06;
45        /* 6   */ 8'h36: keyb_xt = 8'h07;
46        /* 7   */ 8'h3D: keyb_xt = 8'h08;
47        /* 8   */ 8'h3E: keyb_xt = 8'h09;
48        /* 9   */ 8'h46: keyb_xt = 8'h0A;
49        /* ~   */ 8'h0E: keyb_xt = 8'h29;
50        /* -   */ 8'h4E: keyb_xt = 8'h0C;
51        /* =   */ 8'h55: keyb_xt = 8'h0D;
52        /* \   */ 8'h5D: keyb_xt = 8'h2B;
53        /* [   */ 8'h54: keyb_xt = 8'h1A;
54        /* ]   */ 8'h5B: keyb_xt = 8'h1B;
55        /* ;   */ 8'h4C: keyb_xt = 8'h27;
56        /* '   */ 8'h52: keyb_xt = 8'h28;
57        /* ,   */ 8'h41: keyb_xt = 8'h33;
58        /* .   */ 8'h49: keyb_xt = 8'h34;
59        /* /   */ 8'h4A: keyb_xt = 8'h35;
60        /* BS  */ 8'h66: keyb_xt = 8'h0E;
61        /* SPC */ 8'h29: keyb_xt = 8'h39;
62        /* TAB */ 8'h0D: keyb_xt = 8'h0F;
63
64        /* Кнопки модификации */
65        /* CAP */ 8'h58: keyb_xt = 8'h3A; /* CAPS LOCK */
66        /* LSH */ 8'h12: keyb_xt = 8'h2A; /* LEFT SHIFT */
67        /* LCT */ 8'h14: keyb_xt = 8'h1D; /* LEFT CTRL */
68        /* LAT */ 8'h11: keyb_xt = 8'h38; /* LEFT ALT */
69        /* LWI */ 8'h1F: keyb_xt = 8'h5B; /* LEFT WIN */
70        /* RSH */ 8'h59: keyb_xt = 8'h36; /* RIGHT SHIFT */
71        /* RWI */ 8'h27: keyb_xt = 8'h5C; /* RIGHT WIN */
72        /* MNU */ 8'h2F: keyb_xt = 8'h5D; /* MENU */
73        /* ENT */ 8'h5A: keyb_xt = 8'h1C; /* ENTER */
74
75        /* Функциональная панель */
76        /* ESC */ 8'h76: keyb_xt = 8'h01;
77        /* F1  */ 8'h05: keyb_xt = 8'h3B;
78        /* F2  */ 8'h06: keyb_xt = 8'h3C;
79        /* F3  */ 8'h04: keyb_xt = 8'h3D;
80        /* F4  */ 8'h0C: keyb_xt = 8'h3E;
81        /* F5  */ 8'h03: keyb_xt = 8'h3F;
82        /* F6  */ 8'h0B: keyb_xt = 8'h40;
83        /* F7  */ 8'h83: keyb_xt = 8'h41;
84        /* F8  */ 8'h0A: keyb_xt = 8'h42;
85        /* F9  */ 8'h01: keyb_xt = 8'h43;
86        /* F10 */ 8'h09: keyb_xt = 8'h44;
87        /* F11 */ 8'h78: keyb_xt = 8'h57;
88        /* F12 */ 8'h07: keyb_xt = 8'h58;
89        /* SCL */ 8'h7E: keyb_xt = 8'h46;
90
91        /* Цифровая клавиатура */
92        /* NUM */ 8'h77: keyb_xt = 8'h45;
93        /* *   */ 8'h7C: keyb_xt = 8'h37;
94        /* -   */ 8'h7B: keyb_xt = 8'h4A;
95        /* +   */ 8'h79: keyb_xt = 8'h4E;
96        /* .   */ 8'h71: keyb_xt = 8'h53;
97        /* 0   */ 8'h70: keyb_xt = 8'h52;
98        /* 1   */ 8'h69: keyb_xt = 8'h4F;
99        /* 2   */ 8'h72: keyb_xt = 8'h50;
100        /* 3   */ 8'h7A: keyb_xt = 8'h51;
101        /* 4   */ 8'h6B: keyb_xt = 8'h4B;
102        /* 5   */ 8'h73: keyb_xt = 8'h4C;
103        /* 6   */ 8'h74: keyb_xt = 8'h4D;
104        /* 7   */ 8'h6C: keyb_xt = 8'h47;
105        /* 8   */ 8'h75: keyb_xt = 8'h48;
106        /* 9   */ 8'h7D: keyb_xt = 8'h49;
107
108        /* E0, E1, ... */
109        default: keyb_xt = ps2_data;
110
111    endcase
112
113end
114
115reg keyb_unpressed = 1'b0;
116
117/* Принятие данных из PS/2 */
118always @(posedge clock50) begin
119
120    // Новые данные присутствуют. Асинхронный прием.
121    if (ps2_data_clk) begin
122
123        /* Этот скан-код является кодом AT, который сигнализирует, что
124           клавиша отжимается. Для преобразования в XT-скан код, не нужно
125           показывать, что эта клавиша отжата */
126
127        if (ps2_data == 8'hF0) begin
128
129            keyb_unpressed <= 1'b1;
130
131        end else begin
132
133            /* Запись сконвертированного из AT -> XT */
134            /* Если предыдущий скан-код - это признак отжатия клавиши, то записать 1 в 7-й бит */
135            scancode <= keyb_unpressed ? {1'b1, keyb_xt[6:0]} : keyb_xt;
136
137            /* Вернуть обратно в нормальное положение */
138            keyb_unpressed <= 1'b0;
139
140        end
141
142    end
143
144end
145
146endmodule