OpenCores
URL https://opencores.org/ocsvn/a-z80/a-z80/trunk

Subversion Repositories a-z80

[/] [a-z80/] [trunk/] [host/] [zxspectrum_de1/] [ula/] [zx_kbd.sv] - Blame information for rev 13

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 gdevic
//============================================================================
2 10 gdevic
// ZX Spectrum keyboard input
3 8 gdevic
//
4 10 gdevic
// This module takes scan-codes from the attached PS/2 keyboard and sets
5
// corresponding ZX key bitfields which are read by the 'IN' instructions.
6
//
7 8 gdevic
// PS/2      |  ZX Spectrum
8
// ----------+-----------------
9
// CTRL      |  CAPS SHIFT
10
// ALT       |  SYMBOL SHIFT
11
//
12 10 gdevic
// For convenience, in addition to regular alpha-numeric keys, this code
13
// simulates several other standard symbols on the PS/2 keyboard.
14 8 gdevic
//
15
// PS/2      |  ZX Spectrum
16
// ----------+-----------------
17
// BACKSPACE |  DELETE
18
// Arrows Left, Right, Up, Down
19
// ESC       |  BREAK (CAPS+SPACE)
20 10 gdevic
// SHIFT => PS/2 shift for additional keys: -_ += ;: "' <, >. ?/
21 8 gdevic
//
22
//  Copyright (C) 2014-2016  Goran Devic
23
//
24
//  This program is free software; you can redistribute it and/or modify it
25
//  under the terms of the GNU General Public License as published by the Free
26
//  Software Foundation; either version 2 of the License, or (at your option)
27
//  any later version.
28
//
29
//  This program is distributed in the hope that it will be useful, but WITHOUT
30
//  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
31
//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
32
//  more details.
33
//
34
//  You should have received a copy of the GNU General Public License along
35
//  with this program; if not, write to the Free Software Foundation, Inc.,
36
//  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37
//============================================================================
38
module zx_keyboard
39
(
40
    input wire clk,
41 10 gdevic
    input wire nreset,          // Active low reset
42 8 gdevic
 
43
    // Output ZX-specific keyboard codes when requested by the ULA access
44
    input wire [15:0] A,        // Address bus
45
    output wire [4:0] key_row,  // Output the state of a requested row of keys
46
 
47
    // Input key scan codes from the PS/2 keyboard
48
    input wire [7:0] scan_code, // PS/2 scan-code
49
    input wire scan_code_ready, // Active for 1 clock: a scan code is ready
50
    input wire scan_code_error, // Error receiving PS/2 keyboard data
51
    output wire pressed         // Signal that a key is pressed
52
);
53
 
54
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55
//
56
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57 13 gdevic
reg [4:0] keys [0:7];       // 8 rows of 5 bits each: contains 0 for a pressed key at a specific location, 1 otherwise
58 8 gdevic
 
59 13 gdevic
reg released;               // Tracks "released" scan code (F0): contains 0 when a key is pressed, 1 otherwise
60 8 gdevic
reg extended;               // Tracks "extended" scan code (E0)
61
reg shifted;                // Tracks local "shifted" state
62
 
63
// Calculate a "key is pressed" signal
64
assign pressed = ~(&keys[7] & &keys[6] & &keys[5] & &keys[4] & &keys[3] & &keys[2] & &keys[1] & &keys[0]);
65
 
66
// Output requested row of keys continously
67 10 gdevic
assign key_row =
68
    (~A[8]  ? keys[0] : 5'b11111) &
69
    (~A[9]  ? keys[1] : 5'b11111) &
70
    (~A[10] ? keys[2] : 5'b11111) &
71
    (~A[11] ? keys[3] : 5'b11111) &
72
    (~A[12] ? keys[4] : 5'b11111) &
73
    (~A[13] ? keys[5] : 5'b11111) &
74
    (~A[14] ? keys[6] : 5'b11111) &
75
    (~A[15] ? keys[7] : 5'b11111);
76 8 gdevic
 
77 10 gdevic
always @(posedge clk or negedge nreset)
78 8 gdevic
begin
79 10 gdevic
    if (!nreset) begin
80 8 gdevic
        released <= 0;
81
        extended <= 0;
82
        shifted  <= 0;
83
 
84
        keys[0] <= '1;
85
        keys[1] <= '1;
86
        keys[2] <= '1;
87
        keys[3] <= '1;
88
        keys[4] <= '1;
89
        keys[5] <= '1;
90
        keys[6] <= '1;
91
        keys[7] <= '1;
92
    end else
93
    if (scan_code_ready) begin
94 13 gdevic
        if (scan_code==8'hE0) // Extended code prefix byte
95 8 gdevic
            extended <= 1;
96 13 gdevic
        else if (scan_code==8'hF0) // Break code prefix byte
97 8 gdevic
            released <= 1;
98
        else begin
99
            // Cancel release/extended flags for the next clock
100
            extended <= 0;
101
            released <= 0;
102
 
103
            if (extended) begin
104
                // Extended keys
105
                case (scan_code)
106
                    8'h6B:  begin                       // LEFT
107
                            keys[0][0] <= released;     // CAPS SHIFT
108
                            keys[3][4] <= released;     // 5
109
                            end
110
                    8'h72:  begin                       // DOWN
111
                            keys[0][0] <= released;     // CAPS SHIFT
112
                            keys[4][4] <= released;     // 6
113
                            end
114
                    8'h75:  begin                       // UP
115
                            keys[0][0] <= released;     // CAPS SHIFT
116
                            keys[4][3] <= released;     // 7
117
                            end
118
                    8'h74:  begin                       // RIGHT
119
                            keys[0][0] <= released;     // CAPS SHIFT
120
                            keys[4][2] <= released;     // 8
121
                            end
122
                endcase
123
            end
124
            else begin
125
                // For each PS/2 scan-code, set the ZX keyboard matrix state
126
                case (scan_code)
127
                    8'h12:  shifted <= !released;       // Local SHIFT key (left)
128
                    8'h59:  shifted <= !released;       // Local SHIFT key (right)
129
 
130
                    8'h14:  keys[0][0] <= released;     // CAPS SHIFT = Left or right Ctrl
131
 
132
                    8'h1A:  keys[0][1] <= released;     // Z
133
                    8'h22:  keys[0][2] <= released;     // X
134
                    8'h21:  keys[0][3] <= released;     // C
135
                    8'h2A:  keys[0][4] <= released;     // V
136
 
137
                    8'h1C:  keys[1][0] <= released;     // A
138
                    8'h1B:  keys[1][1] <= released;     // S
139
                    8'h23:  keys[1][2] <= released;     // D
140
                    8'h2B:  keys[1][3] <= released;     // F
141
                    8'h34:  keys[1][4] <= released;     // G
142
 
143
                    8'h15:  keys[2][0] <= released;     // Q
144
                    8'h1D:  keys[2][1] <= released;     // W
145
                    8'h24:  keys[2][2] <= released;     // E
146
                    8'h2D:  keys[2][3] <= released;     // R
147
                    8'h2C:  keys[2][4] <= released;     // T
148
 
149
                    8'h16:  keys[3][0] <= released;     // 1
150
                    8'h1E:  keys[3][1] <= released;     // 2
151
                    8'h26:  keys[3][2] <= released;     // 3
152
                    8'h25:  keys[3][3] <= released;     // 4
153
                    8'h2E:  keys[3][4] <= released;     // 5
154
 
155
                    8'h45:  keys[4][0] <= released;     // 0
156
                    8'h46:  keys[4][1] <= released;     // 9
157
                    8'h3E:  keys[4][2] <= released;     // 8
158
                    8'h3D:  keys[4][3] <= released;     // 7
159
                    8'h36:  keys[4][4] <= released;     // 6
160
 
161
                    8'h4D:  keys[5][0] <= released;     // P
162
                    8'h44:  keys[5][1] <= released;     // O
163
                    8'h43:  keys[5][2] <= released;     // I
164
                    8'h3C:  keys[5][3] <= released;     // U
165
                    8'h35:  keys[5][4] <= released;     // Y
166
 
167
                    8'h5A:  keys[6][0] <= released;     // ENTER
168
                    8'h4B:  keys[6][1] <= released;     // L
169
                    8'h42:  keys[6][2] <= released;     // K
170
                    8'h3B:  keys[6][3] <= released;     // J
171
                    8'h33:  keys[6][4] <= released;     // H
172
 
173
                    8'h29:  keys[7][0] <= released;     // SPACE
174
                    8'h11:  keys[7][1] <= released;     // SYMBOL SHIFT (Red) = Left and right Alt
175
                    8'h3A:  keys[7][2] <= released;     // M
176
                    8'h31:  keys[7][3] <= released;     // N
177
                    8'h32:  keys[7][4] <= released;     // B
178
 
179
                    8'h66:  begin                       // BACKSPACE
180
                            keys[0][0] <= released;
181
                            keys[4][0] <= released;
182
                            end
183
                    8'h76:  begin                       // ESC -> BREAK
184
                            keys[0][0] <= released;     // CAPS SHIFT
185
                            keys[7][0] <= released;     // SPACE
186
                            end
187 13 gdevic
                    // With shifted keys, we need to make inactive (set to 1) other corresponding key
188
                    // Otherwise, it will stay active if the shift was released first
189 8 gdevic
                    8'h4E:  begin                       // - or (shifted) _
190 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
191
                            keys[4][0] <= shifted ? released : 1;     // 0
192
                            keys[6][3] <= shifted ? 1 : released;     // J
193 8 gdevic
                            end
194
                    8'h55:  begin                       // = or (shifted) +
195 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
196
                            keys[6][2] <= shifted ? released : 1;     // K
197
                            keys[6][1] <= shifted ? 1 : released;     // L
198 8 gdevic
                            end
199
                    8'h52:  begin                       // ' or (shifted) "
200 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
201
                            keys[5][0] <= shifted ? released : 1;     // P
202
                            keys[4][3] <= shifted ? 1 : released;     // 7
203 8 gdevic
                            end
204
                    8'h4C:  begin                       // ; or (shifted) :
205 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
206
                            keys[0][1] <= shifted ? released : 1;     // Z
207
                            keys[5][1] <= shifted ? 1 : released;     // O
208 8 gdevic
                            end
209
                    8'h41:  begin                       // , or (shifted) <
210 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
211
                            keys[2][3] <= shifted ? released : 1;     // R
212
                            keys[7][3] <= shifted ? 1 : released;     // N
213 8 gdevic
                            end
214
                    8'h49:  begin                       // . or (shifted) >
215 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
216
                            keys[2][4] <= shifted ? released : 1;     // T
217
                            keys[7][2] <= shifted ? 1 : released;     // M
218 8 gdevic
                            end
219
                    8'h4A:  begin                       // / or (shifted) ?
220 13 gdevic
                            keys[7][1] <= released;     // SYMBOL SHIFT (Red)
221
                            keys[0][3] <= shifted ? released : 1;     // C
222
                            keys[0][4] <= shifted ? 1 : released;     // V
223 8 gdevic
                            end
224
                endcase
225
            end
226
        end
227
    end
228
end
229
 
230
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.