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 10

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
reg [4:0] keys [0:7];       // 8 rows of 5 bits each
58
 
59
reg released;               // Tracks "released" scan code (F0)
60
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
        if (scan_code==8'hE0)
95
            extended <= 1;
96
        else if (scan_code==8'hF0)
97
            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
                // 'released' contains 0 when a key is pressed; 1 otherwise
127
                case (scan_code)
128
                    8'h12:  shifted <= !released;       // Local SHIFT key (left)
129
                    8'h59:  shifted <= !released;       // Local SHIFT key (right)
130
 
131
                    8'h14:  keys[0][0] <= released;     // CAPS SHIFT = Left or right Ctrl
132
 
133
                    8'h1A:  keys[0][1] <= released;     // Z
134
                    8'h22:  keys[0][2] <= released;     // X
135
                    8'h21:  keys[0][3] <= released;     // C
136
                    8'h2A:  keys[0][4] <= released;     // V
137
 
138
                    8'h1C:  keys[1][0] <= released;     // A
139
                    8'h1B:  keys[1][1] <= released;     // S
140
                    8'h23:  keys[1][2] <= released;     // D
141
                    8'h2B:  keys[1][3] <= released;     // F
142
                    8'h34:  keys[1][4] <= released;     // G
143
 
144
                    8'h15:  keys[2][0] <= released;     // Q
145
                    8'h1D:  keys[2][1] <= released;     // W
146
                    8'h24:  keys[2][2] <= released;     // E
147
                    8'h2D:  keys[2][3] <= released;     // R
148
                    8'h2C:  keys[2][4] <= released;     // T
149
 
150
                    8'h16:  keys[3][0] <= released;     // 1
151
                    8'h1E:  keys[3][1] <= released;     // 2
152
                    8'h26:  keys[3][2] <= released;     // 3
153
                    8'h25:  keys[3][3] <= released;     // 4
154
                    8'h2E:  keys[3][4] <= released;     // 5
155
 
156
                    8'h45:  keys[4][0] <= released;     // 0
157
                    8'h46:  keys[4][1] <= released;     // 9
158
                    8'h3E:  keys[4][2] <= released;     // 8
159
                    8'h3D:  keys[4][3] <= released;     // 7
160
                    8'h36:  keys[4][4] <= released;     // 6
161
 
162
                    8'h4D:  keys[5][0] <= released;     // P
163
                    8'h44:  keys[5][1] <= released;     // O
164
                    8'h43:  keys[5][2] <= released;     // I
165
                    8'h3C:  keys[5][3] <= released;     // U
166
                    8'h35:  keys[5][4] <= released;     // Y
167
 
168
                    8'h5A:  keys[6][0] <= released;     // ENTER
169
                    8'h4B:  keys[6][1] <= released;     // L
170
                    8'h42:  keys[6][2] <= released;     // K
171
                    8'h3B:  keys[6][3] <= released;     // J
172
                    8'h33:  keys[6][4] <= released;     // H
173
 
174
                    8'h29:  keys[7][0] <= released;     // SPACE
175
                    8'h11:  keys[7][1] <= released;     // SYMBOL SHIFT (Red) = Left and right Alt
176
                    8'h3A:  keys[7][2] <= released;     // M
177
                    8'h31:  keys[7][3] <= released;     // N
178
                    8'h32:  keys[7][4] <= released;     // B
179
 
180
                    8'h66:  begin                       // BACKSPACE
181
                            keys[0][0] <= released;
182
                            keys[4][0] <= released;
183
                            end
184
                    8'h76:  begin                       // ESC -> BREAK
185
                            keys[0][0] <= released;     // CAPS SHIFT
186
                            keys[7][0] <= released;     // SPACE
187
                            end
188
                    8'h4E:  begin                       // - or (shifted) _
189
                            if (!shifted) begin
190
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
191
                                keys[6][3] <= released;     // J
192
                            end
193
                            else begin
194
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
195
                                keys[4][0] <= released;     // 0
196
                            end
197
                            end
198
                    8'h55:  begin                       // = or (shifted) +
199
                            if (!shifted) begin
200
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
201
                                keys[6][1] <= released;     // L
202
                            end
203
                            else begin
204
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
205
                                keys[6][2] <= released;     // K
206
                            end
207
                            end
208
                    8'h52:  begin                       // ' or (shifted) "
209
                            if (!shifted) begin
210
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
211
                                keys[4][3] <= released;     // 7
212
                            end
213
                            else begin
214
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
215
                                keys[5][0] <= released;     // P
216
                            end
217
                            end
218
                    8'h4C:  begin                       // ; or (shifted) :
219
                            if (!shifted) begin
220
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
221
                                keys[5][1] <= released;     // O
222
                            end
223
                            else begin
224
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
225
                                keys[0][1] <= released;     // Z
226
                            end
227
                            end
228
                    8'h41:  begin                       // , or (shifted) <
229
                            if (!shifted) begin
230
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
231
                                keys[7][3] <= released;     // N
232
                            end
233
                            else begin
234
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
235
                                keys[2][3] <= released;     // R
236
                            end
237
                            end
238
                    8'h49:  begin                       // . or (shifted) >
239
                            if (!shifted) begin
240
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
241
                                keys[7][2] <= released;     // M
242
                            end
243
                            else begin
244
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
245
                                keys[2][4] <= released;     // T
246
                            end
247
                            end
248
                    8'h4A:  begin                       // / or (shifted) ?
249
                            if (!shifted) begin
250
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
251
                                keys[0][4] <= released;     // V
252
                            end
253
                            else begin
254
                                keys[7][1] <= released;     // SYMBOL SHIFT (Red)
255
                                keys[0][3] <= released;     // C
256
                            end
257
                            end
258
                endcase
259
            end
260
        end
261
    end
262
end
263
 
264
endmodule

powered by: WebSVN 2.1.0

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