1
0
mirror of https://github.com/Gehstock/Mist_FPGA.git synced 2026-01-23 02:37:52 +00:00
2019-06-04 17:43:34 +02:00

414 lines
12 KiB
Systemverilog
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

module LaserKeyboard(
input wire CLK50MHZ,
input wire [15:0] CPU_A,
input wire RESET,
input wire CASS_IN,
input wire PS2_KBCLK,
input wire PS2_KBDAT
);
// keyboard
reg [4:0] KB_CLK;
reg [16:0] RESET_KEY_COUNT;
wire [7:0] SCAN;
wire PRESS;
wire PRESS_N;
wire EXTENDED;
reg BOOTROM_EN;
reg [7:0] BOOTROM_BANK;
reg AUTOSTARTROM_EN;
reg [7:0] AUTOSTARTROM_BANK;
reg [63:0] KEY;
reg [9:0] KEY_EX;
reg [11:0] KEY_Fxx;
wire [7:0] KEY_DATA;
//reg [63:0] LAST_KEY;
//reg CAPS_CLK;
//reg CAPS;
wire A_KEY_PRESSED;
reg [7:0] LATCHED_KEY_DATA;
// emu keyboard
wire [63:0] EMU_KEY;
wire [9:0] EMU_KEY_EX;
wire EMU_KEY_EN;
// keyboard
/*****************************************************************************
* Convert PS/2 keyboard to ASCII keyboard
******************************************************************************/
/*
KD5 KD4 KD3 KD2 KD1 KD0 扫描用地址
A0 R Q E W T 68FEH 0
A1 F A D CTRL S G 68FDH 8
A2 V Z C SHFT X B 68FBH 16
A3 4 1 3 2 5 68F7H 24
A4 M 空格 . N 68EFH 32
A5 7 0 8 - 9 6 68DFH 40
A6 U P I RETN O Y 68BFH 48
A7 J K : L H 687FH 56
*/
// 7: 0
// 15: 8
// 23:16
// 31:24
// 39:32
// 47:40
// 55:48
// 63:56
// 键盘检测的方法就是循环地问每一行线发送低电平信号也就是用该地址线为“0”的地址去读取数据。
// 例如检测第一行时使A0为0其余为1加上选通IC4的高五位地址01101成为01101***11111110BA8~A10不起作用
// 可为任意值故68FEH69FEH6AFEH6BFEH6CFEH6DFEH6EFEH6FFEH均可
// 读 6800H 判断是否有按键按下。
// The method of keyboard detection is to cyclically ask each line to send a low level signal,
// that is, to read the data with the address line "0".
// For example, when detecting the first line, make A0 0 and the rest 1; plus the high five-bit address 01101 of the strobe IC4,
// become 01101***11111110B (A8~A10 does not work,
// It can be any value, so 68FEH, 69FEH, 6AFEH, 6BFEH, 6CFEH, 6DFEH, 6EFEH, 6FFEH can be).
// Read 6800H to determine if there is a button press.
// 键盘选通整个竖列有一个选通的位置被按下对应值为0。
// The keyboard is strobed, and a strobe position is pressed in the entire vertical column, and the corresponding value is 0.
// 键盘扩展
// 加入方向键盘
// Keyboard extension
// left: ctrl M 37 KEY_EX[5]
// right: ctrl , 35 KEY_EX[6]
// up: ctrl . 33 KEY_EX[4]
// down: ctrl space 36 KEY_EX[7]
// esc: ctrl - 42 KEY_EX[3]
// backspace: ctrl M 37 KEY_EX[8]
// R-Shift
wire [63:0] KEY_C = EMU_KEY_EN?EMU_KEY:KEY;
wire [9:0] KEY_EX_C = EMU_KEY_EN?EMU_KEY_EX:KEY_EX;
//wire KEY_CTRL_ULRD = (KEY_EX[7:4]==4'b1111);
wire KEY_CTRL_ULRD_BRK = (KEY_EX[8:3]==6'b111111);
wire KEY_DATA_BIT5 = (CPU_A[7:0]|{KEY_C[61], KEY_C[53], KEY_C[45], KEY_C[37]&KEY_EX_C[5]&KEY_EX_C[8], KEY_C[29], KEY_C[21], KEY_C[13], KEY_C[ 5]})==8'hff;
wire KEY_DATA_BIT4 = (CPU_A[7:0]|{KEY_C[60], KEY_C[52], KEY_C[44], KEY_C[36]&KEY_EX_C[7], KEY_C[28], KEY_C[20], KEY_C[12], KEY_C[ 4]})==8'hff;
wire KEY_DATA_BIT3 = (CPU_A[7:0]|{KEY_C[59], KEY_C[51], KEY_C[43], KEY_C[35]&KEY_EX_C[6], KEY_C[27], KEY_C[19], KEY_C[11], KEY_C[ 3]})==8'hff;
wire KEY_DATA_BIT2 = (CPU_A[7:0]|{KEY_C[58], KEY_C[50], KEY_C[42]&KEY_EX_C[3], KEY_C[34], KEY_C[26], KEY_C[18]&KEY_EX_C[0], KEY_C[10]&KEY_CTRL_ULRD_BRK, KEY_C[ 2]})==8'hff;
wire KEY_DATA_BIT1 = (CPU_A[7:0]|{KEY_C[57], KEY_C[49], KEY_C[41], KEY_C[33]&KEY_EX_C[4], KEY_C[25], KEY_C[17], KEY_C[ 9], KEY_C[ 1]})==8'hff;
wire KEY_DATA_BIT0 = (CPU_A[7:0]|{KEY_C[56], KEY_C[48], KEY_C[40], KEY_C[32], KEY_C[24], KEY_C[16], KEY_C[ 8], KEY_C[ 0]})==8'hff;
/*
wire KEY_DATA_BIT5 = (CPU_A[7:0]|{KEY[61], KEY[53], KEY[45], KEY[37], KEY[29], KEY[21], KEY[13], KEY[ 5]})==8'hff;
wire KEY_DATA_BIT4 = (CPU_A[7:0]|{KEY[60], KEY[52], KEY[44], KEY[36], KEY[28], KEY[20], KEY[12], KEY[ 4]})==8'hff;
wire KEY_DATA_BIT3 = (CPU_A[7:0]|{KEY[59], KEY[51], KEY[43], KEY[35], KEY[27], KEY[19], KEY[11], KEY[ 3]})==8'hff;
wire KEY_DATA_BIT2 = (CPU_A[7:0]|{KEY[58], KEY[50], KEY[42], KEY[34], KEY[26], KEY[18], KEY[10], KEY[ 2]})==8'hff;
wire KEY_DATA_BIT1 = (CPU_A[7:0]|{KEY[57], KEY[49], KEY[41], KEY[33], KEY[25], KEY[17], KEY[ 9], KEY[ 1]})==8'hff;
wire KEY_DATA_BIT0 = (CPU_A[7:0]|{KEY[56], KEY[48], KEY[40], KEY[32], KEY[24], KEY[16], KEY[ 8], KEY[ 0]})==8'hff;
*/
wire KEY_DATA_BIT7 = 1'b1; // 没有空置,具体用途没有理解
//wire KEY_DATA_BIT6 = CASS_IN;
wire KEY_DATA_BIT6 = ~CASS_IN;
assign KEY_DATA = { KEY_DATA_BIT7, KEY_DATA_BIT6, KEY_DATA_BIT5, KEY_DATA_BIT4, KEY_DATA_BIT3, KEY_DATA_BIT2, KEY_DATA_BIT1, KEY_DATA_BIT0 };
/*
assign KEY_DATA = (CPU_A[0]==1'b0) ? KEY[ 7: 0] :
(CPU_A[1]==1'b0) ? KEY[15: 8] :
(CPU_A[2]==1'b0) ? KEY[23:16] :
(CPU_A[3]==1'b0) ? KEY[31:24] :
(CPU_A[4]==1'b0) ? KEY[39:32] :
(CPU_A[5]==1'b0) ? KEY[47:40] :
(CPU_A[6]==1'b0) ? KEY[55:48] :
(CPU_A[7]==1'b0) ? KEY[63:56] :
8'hff;
assign KEY_DATA =
(CPU_A[7]==1'b0) ? KEY[63:56] :
(CPU_A[6]==1'b0) ? KEY[55:48] :
(CPU_A[5]==1'b0) ? KEY[47:40] :
(CPU_A[4]==1'b0) ? KEY[39:32] :
(CPU_A[3]==1'b0) ? KEY[31:24] :
(CPU_A[2]==1'b0) ? KEY[23:16] :
(CPU_A[1]==1'b0) ? KEY[15: 8] :
(CPU_A[0]==1'b0) ? KEY[ 7: 0] :
8'hff;
*/
assign A_KEY_PRESSED = (KEY[63:0] == 64'hFFFFFFFFFFFFFFFF) ? 1'b0:1'b1;
always @(posedge KB_CLK[3] or negedge RESET)
begin
if(~RESET)
begin
KEY <= 64'hFFFFFFFFFFFFFFFF;
KEY_EX <= 10'h3FF;
KEY_Fxx <= 12'h000;
// CAPS_CLK <= 1'b0;
RESET_KEY_COUNT <= 17'h1FFFF;
BOOTROM_BANK <= 0;
BOOTROM_EN <= 1'b0;
AUTOSTARTROM_BANK <= 0;
AUTOSTARTROM_EN <= 1'b0;
end
else
begin
//KEY[?] <= CAPS;
if(RESET_KEY_COUNT[16]==1'b0)
RESET_KEY_COUNT <= RESET_KEY_COUNT+1;
case(SCAN)
/*8'h07:
begin
KEY_Fxx[11] <= PRESS; // F12 RESET
if(PRESS && (KEY[10]==PRESS_N))
begin
BOOTROM_EN <= 1'b0;
BOOTROM_BANK <= 0;
AUTOSTARTROM_EN <= 1'b0;
AUTOSTARTROM_BANK <= 0;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h78: KEY_Fxx[10] <= PRESS; // F11
8'h09: KEY_Fxx[ 9] <= PRESS; // F10 CASS STOP
8'h01: KEY_Fxx[ 8] <= PRESS; // F9 CASS PLAY
8'h0A:
begin
KEY_Fxx[ 7] <= PRESS; // F8 Ctrl or L-Shift BOOT 8
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 39;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 23;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h83:
begin
KEY_Fxx[ 6] <= PRESS; // F7 Ctrl or L-Shift BOOT 7
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 38;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 22;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h0B:
begin
KEY_Fxx[ 5] <= PRESS; // F6 Ctrl or L-Shift BOOT 6
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 37;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 21;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h03:
begin
KEY_Fxx[ 4] <= PRESS; // F5 Ctrl or L-Shift BOOT 5
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 36;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 20;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h0C:
begin
KEY_Fxx[ 3] <= PRESS; // F4 Ctrl or L-Shift BOOT 4
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 35;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 19;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h04:
begin
KEY_Fxx[ 2] <= PRESS; // F3 Ctrl or L-Shift BOOT 3
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 34;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 18;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h06:
begin
KEY_Fxx[ 1] <= PRESS; // F2 Ctrl or L-Shift BOOT 2
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 33;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 17;
RESET_KEY_COUNT <= 17'h0;
end
end
8'h05:
begin
KEY_Fxx[ 0] <= PRESS; // F1 Ctrl or L-Shift BOOT 1
if(PRESS && (KEY[18]==PRESS_N))
begin
BOOTROM_EN <= 1'b1;
BOOTROM_BANK <= 32;
RESET_KEY_COUNT <= 17'h0;
end
else
if(PRESS && (KEY[10]==PRESS_N))
begin
AUTOSTARTROM_EN <= 1'b1;
AUTOSTARTROM_BANK <= 16;
RESET_KEY_COUNT <= 17'h0;
end
end*/
8'h16: KEY[28] <= PRESS_N; // 1 !
8'h1E: KEY[25] <= PRESS_N; // 2 @
8'h26: KEY[27] <= PRESS_N; // 3 #
8'h25: KEY[29] <= PRESS_N; // 4 $
8'h2E: KEY[24] <= PRESS_N; // 5 %
8'h36: KEY[40] <= PRESS_N; // 6 ^
8'h3D: KEY[45] <= PRESS_N; // 7 &
// 8'h0D: KEY[?] <= PRESS_N; // TAB
8'h3E: KEY[43] <= PRESS_N; // 8 *
8'h46: KEY[41] <= PRESS_N; // 9 (
8'h45: KEY[44] <= PRESS_N; // 0 )
8'h4E: KEY[42] <= PRESS_N; // - _
// 8'h55: KEY[?] <= PRESS_N; // = +
8'h66: KEY_EX[8] <= PRESS_N; // backspace
// 8'h0E: KEY[?] <= PRESS_N; // ` ~
// 8'h5D: KEY[?] <= PRESS_N; // \ |
8'h49: KEY[33] <= PRESS_N; // . >
8'h4b: KEY[57] <= PRESS_N; // L
8'h44: KEY[49] <= PRESS_N; // O
// 8'h11 KEY[?] <= PRESS_N; // line feed (really right ALT (Extended) see below
8'h5A: KEY[50] <= PRESS_N; // CR
// 8'h54: KEY[?] <= PRESS_N; // [ {
// 8'h5B: KEY[?] <= PRESS_N; // ] }
8'h52: KEY[58] <= PRESS_N; // ' "
8'h1D: KEY[ 1] <= PRESS_N; // W
8'h24: KEY[ 3] <= PRESS_N; // E
8'h2D: KEY[ 5] <= PRESS_N; // R
8'h2C: KEY[ 0] <= PRESS_N; // T
8'h35: KEY[48] <= PRESS_N; // Y
8'h3C: KEY[53] <= PRESS_N; // U
8'h43: KEY[51] <= PRESS_N; // I
8'h1B: KEY[ 9] <= PRESS_N; // S
8'h23: KEY[11] <= PRESS_N; // D
8'h2B: KEY[13] <= PRESS_N; // F
8'h34: KEY[ 8] <= PRESS_N; // G
8'h33: KEY[56] <= PRESS_N; // H
8'h3B: KEY[61] <= PRESS_N; // J
8'h42: KEY[59] <= PRESS_N; // K
8'h22: KEY[17] <= PRESS_N; // X
8'h21: KEY[19] <= PRESS_N; // C
8'h2a: KEY[21] <= PRESS_N; // V
8'h32: KEY[16] <= PRESS_N; // B
8'h31: KEY[32] <= PRESS_N; // N
8'h3a: KEY[37] <= PRESS_N; // M
8'h41: KEY[35] <= PRESS_N; // , <
8'h15: KEY[ 4] <= PRESS_N; // Q
8'h1C: KEY[12] <= PRESS_N; // A
8'h1A: KEY[20] <= PRESS_N; // Z
8'h29: KEY[36] <= PRESS_N; // Space
// 8'h4A: KEY[?] <= PRESS_N; // / ?
8'h4C: KEY[60] <= PRESS_N; // ; :
8'h4D: KEY[52] <= PRESS_N; // P
8'h14: KEY[10] <= PRESS_N; // Ctrl either left or right
8'h12: KEY[18] <= PRESS_N; // L-Shift
8'h59: KEY_EX[0] <= PRESS_N; // R-Shift
8'h11:
begin
if(~EXTENDED)
KEY_EX[1] <= PRESS_N; // Repeat really left ALT
else
KEY_EX[2] <= PRESS_N; // LF really right ALT
end
8'h76: KEY_EX[3] <= PRESS_N; // Esc
8'h75: KEY_EX[4] <= PRESS_N; // up
8'h6B: KEY_EX[5] <= PRESS_N; // left
8'h74: KEY_EX[6] <= PRESS_N; // right
8'h72: KEY_EX[7] <= PRESS_N; // down
endcase
end
end
always @ (posedge CLK50MHZ) // 50MHz
KB_CLK <= KB_CLK + 1'b1; // 50/32 = 1.5625 MHz
ps2_keyboard KEYBOARD(
.RESET_N(~RESET),
.CLK(KB_CLK[4]),
.PS2_CLK(PS2_KBCLK),
.PS2_DATA(PS2_KBDAT),
.RX_SCAN(SCAN),
.RX_PRESSED(PRESS),
.RX_EXTENDED(EXTENDED)
);
assign PRESS_N = ~PRESS;
endmodule