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 8

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

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

powered by: WebSVN 2.1.0

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