add fifo for ps/2 keyboard scancodes (#1)

This commit is contained in:
Eugene Lozovoy
2024-10-03 20:36:55 +03:00
parent 858e4a2a61
commit 8a1898cf8e
3 changed files with 354 additions and 269 deletions

View File

@ -6,6 +6,8 @@ module keyboard
output [4:0] keyb, output [4:0] keyb,
output reg key_reset, output reg key_reset,
output reg [7:0] scancode, output reg [7:0] scancode,
input scancode_ack,
input scancode_clr,
input [10:0] ps2_key, input [10:0] ps2_key,
input [1:0] cfg_joystick1, input [1:0] cfg_joystick1,
input [1:0] cfg_joystick2, input [1:0] cfg_joystick2,
@ -69,76 +71,76 @@ always @(posedge clk) begin
case (cfg_joystick1) case (cfg_joystick1)
2'b01: begin // Sinclair 1 2'b01: begin // Sinclair 1
case (joys_chn) case (joys_chn)
0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h3d}; // Right | 7 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h3d}; // Right | 7
1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h36}; // Left | 6 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h36}; // Left | 6
2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h3e}; // Down | 8 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h3e}; // Down | 8
3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h46}; // Up | 9 3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h46}; // Up | 9
4: {strobe, press, code} <= {1'b1, joys[4 ], 9'h45}; // Fire 1 | 0 4: {strobe, press, code} <= {1'b1, joys[4 ], 9'h45}; // Fire 1 | 0
5: {strobe, press, code} <= {1'b1, joys[5 ], 9'h3a}; // Fire 2 | m 5: {strobe, press, code} <= {1'b1, joys[5 ], 9'h3a}; // Fire 2 | m
6: {strobe, press, code} <= {1'b1, joys[6 ], 9'h31}; // Fire 3 | n 6: {strobe, press, code} <= {1'b1, joys[6 ], 9'h31}; // Fire 3 | n
7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h32}; // Fire 4 | b 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h32}; // Fire 4 | b
endcase endcase
end end
2'b10: begin // Sinclair 2 2'b10: begin // Sinclair 2
case (joys_chn) case (joys_chn)
0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h1e}; // Right | 2 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h1e}; // Right | 2
1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h16}; // Left | 1 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h16}; // Left | 1
2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h26}; // Down | 3 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h26}; // Down | 3
3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h25}; // Up | 4 3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h25}; // Up | 4
4: {strobe, press, code} <= {1'b1, joys[4 ], 9'h2e}; // Fire 1 | 5 4: {strobe, press, code} <= {1'b1, joys[4 ], 9'h2e}; // Fire 1 | 5
5: {strobe, press, code} <= {1'b1, joys[5 ], 9'h1a}; // Fire 2 | z 5: {strobe, press, code} <= {1'b1, joys[5 ], 9'h1a}; // Fire 2 | z
6: {strobe, press, code} <= {1'b1, joys[6 ], 9'h22}; // Fire 3 | x 6: {strobe, press, code} <= {1'b1, joys[6 ], 9'h22}; // Fire 3 | x
7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h21}; // Fire 4 | c 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h21}; // Fire 4 | c
endcase endcase
end end
2'b11: begin // Cursor 2'b11: begin // Cursor
case (joys_chn) case (joys_chn)
0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h74}; // Right | Right 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h174}; // Right | Right
1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h6b}; // Left | Left 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h16b}; // Left | Left
2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h72}; // Down | Down 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h172}; // Down | Down
3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h75}; // Up | Up 3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h175}; // Up | Up
4: {strobe, press, code} <= {1'b1, joys[4 ], 9'h5a}; // Fire 1 | Enter 4: {strobe, press, code} <= {1'b1, joys[4 ], 9'h5a}; // Fire 1 | Enter
5: {strobe, press, code} <= {1'b1, joys[5 ], 9'h0d}; // Fire 2 | Tab 5: {strobe, press, code} <= {1'b1, joys[5 ], 9'h0d}; // Fire 2 | Tab
6: {strobe, press, code} <= {1'b1, joys[6 ], 9'h29}; // Fire 3 | Space 6: {strobe, press, code} <= {1'b1, joys[6 ], 9'h29}; // Fire 3 | Space
7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h76}; // Fire 4 | Esc 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h76}; // Fire 4 | Esc
endcase endcase
end end
endcase endcase
case (cfg_joystick2) case (cfg_joystick2)
2'b01: begin // Sinclair 1 2'b01: begin // Sinclair 1
case (joys_chn) case (joys_chn)
8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h3d}; // Right | 7 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h3d}; // Right | 7
9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h36}; // Left | 6 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h36}; // Left | 6
10: {strobe, press, code} <= {1'b1, joys[10], 9'h3e}; // Down | 8 10: {strobe, press, code} <= {1'b1, joys[10], 9'h3e}; // Down | 8
11: {strobe, press, code} <= {1'b1, joys[11], 9'h46}; // Up | 9 11: {strobe, press, code} <= {1'b1, joys[11], 9'h46}; // Up | 9
12: {strobe, press, code} <= {1'b1, joys[12], 9'h45}; // Fire 1 | 0 12: {strobe, press, code} <= {1'b1, joys[12], 9'h45}; // Fire 1 | 0
13: {strobe, press, code} <= {1'b1, joys[13], 9'h3a}; // Fire 2 | m 13: {strobe, press, code} <= {1'b1, joys[13], 9'h3a}; // Fire 2 | m
14: {strobe, press, code} <= {1'b1, joys[14], 9'h31}; // Fire 3 | n 14: {strobe, press, code} <= {1'b1, joys[14], 9'h31}; // Fire 3 | n
15: {strobe, press, code} <= {1'b1, joys[15], 9'h32}; // Fire 4 | b 15: {strobe, press, code} <= {1'b1, joys[15], 9'h32}; // Fire 4 | b
endcase endcase
end end
2'b10: begin // Sinclair 2 2'b10: begin // Sinclair 2
case (joys_chn) case (joys_chn)
8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h1e}; // Right | 2 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h1e}; // Right | 2
9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h16}; // Left | 1 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h16}; // Left | 1
10: {strobe, press, code} <= {1'b1, joys[10], 9'h26}; // Down | 3 10: {strobe, press, code} <= {1'b1, joys[10], 9'h26}; // Down | 3
11: {strobe, press, code} <= {1'b1, joys[11], 9'h25}; // Up | 4 11: {strobe, press, code} <= {1'b1, joys[11], 9'h25}; // Up | 4
12: {strobe, press, code} <= {1'b1, joys[12], 9'h2e}; // Fire 1 | 5 12: {strobe, press, code} <= {1'b1, joys[12], 9'h2e}; // Fire 1 | 5
13: {strobe, press, code} <= {1'b1, joys[13], 9'h1a}; // Fire 2 | z 13: {strobe, press, code} <= {1'b1, joys[13], 9'h1a}; // Fire 2 | z
14: {strobe, press, code} <= {1'b1, joys[14], 9'h22}; // Fire 3 | x 14: {strobe, press, code} <= {1'b1, joys[14], 9'h22}; // Fire 3 | x
15: {strobe, press, code} <= {1'b1, joys[15], 9'h21}; // Fire 4 | c 15: {strobe, press, code} <= {1'b1, joys[15], 9'h21}; // Fire 4 | c
endcase endcase
end end
2'b11: begin // Cursor 2'b11: begin // Cursor
case (joys_chn) case (joys_chn)
8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h74}; // Right | Right 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h174}; // Right | Right
9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h6b}; // Left | Left 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h16b}; // Left | Left
10: {strobe, press, code} <= {1'b1, joys[10], 9'h72}; // Down | Down 10: {strobe, press, code} <= {1'b1, joys[10], 9'h172}; // Down | Down
11: {strobe, press, code} <= {1'b1, joys[11], 9'h75}; // Up | Up 11: {strobe, press, code} <= {1'b1, joys[11], 9'h175}; // Up | Up
12: {strobe, press, code} <= {1'b1, joys[12], 9'h5a}; // Fire 1 | Enter 12: {strobe, press, code} <= {1'b1, joys[12], 9'h5a}; // Fire 1 | Enter
13: {strobe, press, code} <= {1'b1, joys[13], 9'h0d}; // Fire 2 | Tab 13: {strobe, press, code} <= {1'b1, joys[13], 9'h0d}; // Fire 2 | Tab
14: {strobe, press, code} <= {1'b1, joys[14], 9'h29}; // Fire 3 | Space 14: {strobe, press, code} <= {1'b1, joys[14], 9'h29}; // Fire 3 | Space
15: {strobe, press, code} <= {1'b1, joys[15], 9'h76}; // Fire 4 | Esc 15: {strobe, press, code} <= {1'b1, joys[15], 9'h76}; // Fire 4 | Esc
endcase endcase
end end
endcase endcase
@ -157,14 +159,9 @@ always @(posedge clk or posedge reset) begin
keys[6] <= 5'b11111; keys[6] <= 5'b11111;
keys[7] <= 5'b11111; keys[7] <= 5'b11111;
key_reset <= 0; key_reset <= 0;
scancode <= 0;
end end
else begin else begin
if (strobe) begin if (strobe) begin
if (press)
scancode <= code[7:0];
else
scancode <= 8'hFF;
case (code[7:0]) case (code[7:0])
8'h12: keys[0][0] <= ~press; // Left shift (CAPS SHIFT) 8'h12: keys[0][0] <= ~press; // Left shift (CAPS SHIFT)
8'h59: keys[0][0] <= ~press; // Right shift (CAPS SHIFT) 8'h59: keys[0][0] <= ~press; // Right shift (CAPS SHIFT)
@ -297,4 +294,77 @@ always @(posedge clk or posedge reset) begin
end end
end end
reg fifo_rdreq;
wire [9:0] fifo_q;
wire fifo_empty;
scfifo
#(
.lpm_width(10),
.lpm_widthu(6),
.lpm_numwords(64),
.lpm_showahead("OFF"),
.overflow_checking("ON"),
.underflow_checking("OFF"),
.add_ram_output_register("ON")
)
fifo_scancodes
(
.clock(clk),
.data({~press, code}),
.wrreq(strobe),
.rdreq(fifo_rdreq),
.sclr(scancode_clr),
.q(fifo_q),
.empty(fifo_empty)
);
reg [1:0] step = 0;
always @(posedge clk) begin
fifo_rdreq <= 0;
scancode <= 0;
case (step)
2'd0: begin
if (!fifo_empty) begin
fifo_rdreq <= 1'b1;
step <= step + 1'b1;
end
end
2'd1: begin
if (fifo_q[8])
scancode <= 8'hE0;
else if (fifo_q[9])
scancode <= 8'hF0;
else
scancode <= fifo_q[7:0];
if (scancode_ack)
step <= step + 1'b1;
end
2'd2: begin
if (fifo_q[9] && fifo_q[8])
scancode <= 8'hF0;
else if (fifo_q[8] || fifo_q[9])
scancode <= fifo_q[7:0];
if (scancode_ack)
step <= step + 1'b1;
end
2'd3: begin
if (fifo_q[9] && fifo_q[8])
scancode <= fifo_q[7:0];
if (scancode_ack)
step <= step + 1'b1;
end
endcase
if (scancode_clr)
step <= 0;
end
endmodule endmodule

View File

@ -1,241 +1,249 @@
//-----------------------------------------------------------------[18.10.2014]
// MC146818A REAL-TIME CLOCK PLUS RAM
//-----------------------------------------------------------------------------
// V0.1 05.10.2011 Initial version
// V0.2 06.09.2014 Added General Purpose RAM
module mc146818a module mc146818a
( (
input RESET, input RESET,
input CLK, input CLK,
input ENA, input ENA,
input CS, input CS,
input [64:0] RTC, input [64:0] RTC,
input [7:0] KEYSCANCODE, input [7:0] KEYSCANCODE,
output reg KEYSCANCODE_ACK,
output reg KEYSCANCODE_CLR,
input WR, input RD,
input [7:0] A, input WR,
input [7:0] DI, input [7:0] A,
output [7:0] DO, input [7:0] DI,
output reg [7:0] DO,
input loader_WR, input loader_WR,
input [7:0] loader_A, input [7:0] loader_A,
input [7:0] loader_DI, input [7:0] loader_DI,
output [7:0] loader_DO output [7:0] loader_DO
); );
reg [18:0] pre_scaler =0; reg [18:0] pre_scaler =0;
reg [1:0] leap_reg =0; reg [1:0] leap_reg =0;
reg [7:0] seconds_reg =0; // 00 reg [7:0] seconds_reg =0; // 00
reg [7:0] seconds_alarm_reg =0; // 01 reg [7:0] seconds_alarm_reg =0; // 01
reg [7:0] minutes_reg =0; // 02 reg [7:0] minutes_reg =0; // 02
reg [7:0] minutes_alarm_reg = 0;// 03 reg [7:0] minutes_alarm_reg = 0; // 03
reg [7:0] hours_reg =0; // 04 reg [7:0] hours_reg =0; // 04
reg [7:0] hours_alarm_reg ='hff;// 05 reg [7:0] hours_alarm_reg ='hff; // 05
reg [7:0] weeks_reg = 1; // 06 reg [7:0] weeks_reg = 1; // 06
reg [7:0] days_reg = 1; // 07 reg [7:0] days_reg = 1; // 07
reg [7:0] month_reg = 1; // 08 reg [7:0] month_reg = 1; // 08
reg [7:0] year_reg = 0; // 09 reg [7:0] year_reg = 0; // 09
reg [7:0] a_reg; // 0A reg [7:0] a_reg; // 0A
reg [7:0] b_reg = 8'b00000010; // 0B reg [7:0] b_reg = 8'b00000010; // 0B
reg [7:0] c_reg; // 0C reg [7:0] c_reg; // 0C
reg keyrd_enable = 0;
reg keyrd = 0;
always @(posedge CLK) begin
KEYSCANCODE_ACK <= !RD && keyrd;
keyrd <= keyrd_enable && RD && CS && A[7:4] == 4'hf;
end
wire [7:0] CMOS_Dout; wire [7:0] CMOS_Dout;
reg [7:0] Dout; always @(posedge CLK) begin
if (RD & CS) begin
casez (A[7:0])
8'h00 : DO <= seconds_reg;
8'h01 : DO <= seconds_alarm_reg;
8'h02 : DO <= minutes_reg;
8'h03 : DO <= minutes_alarm_reg;
8'h04 : DO <= hours_reg;
8'h05 : DO <= hours_alarm_reg;
8'h06 : DO <= weeks_reg;
8'h07 : DO <= days_reg;
8'h08 : DO <= month_reg;
8'h09 : DO <= year_reg;
8'h0a : DO <= a_reg;
8'h0b : DO <= b_reg;
8'h0c : DO <= c_reg;
8'h0d : DO <= 8'b10000000;
assign DO = Dout; 8'hf? : DO <= KEYSCANCODE;
default: DO <= CMOS_Dout;
always @(*) begin endcase
case (A[7:0]) end
8'h00 : Dout <= seconds_reg;
8'h01 : Dout <= seconds_alarm_reg;
8'h02 : Dout <= minutes_reg;
8'h03 : Dout <= minutes_alarm_reg;
8'h04 : Dout <= hours_reg;
8'h05 : Dout <= hours_alarm_reg;
8'h06 : Dout <= weeks_reg;
8'h07 : Dout <= days_reg;
8'h08 : Dout <= month_reg;
8'h09 : Dout <= year_reg;
8'h0a : Dout <= a_reg;
8'h0b : Dout <= b_reg;
8'h0c : Dout <= c_reg;
8'h0d : Dout <= 8'b10000000;
8'hf0 : Dout <= KEYSCANCODE;
default: Dout <= CMOS_Dout;
endcase
end end
always @(posedge CLK) begin always @(posedge CLK) begin
if (RTC[62] && !b_reg[7]) begin KEYSCANCODE_CLR <= 1'b0;
seconds_reg <= RTC[7:0];
minutes_reg <= RTC[15:8];
hours_reg <= RTC[23:16];
days_reg <= RTC[31:24];
month_reg <= RTC[39:32];
year_reg <= RTC[47:40];
weeks_reg <= RTC[55:48] + 1'b1;
b_reg <= 8'b00000010;
end
if (RESET) b_reg <= 8'b00000010; if (RTC[62] && !b_reg[7]) begin
else if (WR & CS) begin seconds_reg <= RTC[7:0];
/* minutes_reg <= RTC[15:8];
case (A[7:0]) hours_reg <= RTC[23:16];
0 : seconds_reg <= DI; days_reg <= RTC[31:24];
1 : seconds_alarm_reg <= DI; month_reg <= RTC[39:32];
2 : minutes_reg <= DI; year_reg <= RTC[47:40];
3 : minutes_alarm_reg <= DI; weeks_reg <= RTC[55:48] + 1'b1;
4 : hours_reg <= DI; b_reg <= 8'b00000010;
5 : hours_alarm_reg <= DI; end
6 : weeks_reg <= DI;
7 : days_reg <= DI;
8 : month_reg <= DI;
9 : year_reg <= DI;
11 : begin
b_reg <= DI;
if (b_reg[2] == 1'b0) begin // BCD to BIN convertion
if (DI[4] == 1'b0) leap_reg <= DI[1:0];
else leap_reg <= {~DI[1], DI[0]};
end
else begin
leap_reg <= DI[1:0];
end
end
endcase
*/
end
if (RESET) begin if (RESET) b_reg <= 8'b00000010;
a_reg <= 8'b00100110; else if (WR & CS) begin
c_reg <= 0; casez (A[7:0])
end 8'h00 : seconds_reg <= DI;
else if (~b_reg[7] & ENA) begin 8'h01 : seconds_alarm_reg <= DI;
if (pre_scaler) begin 8'h02 : minutes_reg <= DI;
pre_scaler <= pre_scaler - 1'd1; 8'h03 : minutes_alarm_reg <= DI;
a_reg[7] <= 0; 8'h04 : hours_reg <= DI;
end 8'h05 : hours_alarm_reg <= DI;
else begin 8'h06 : weeks_reg <= DI;
pre_scaler <= 437500; //(0.4375MHz) 8'h07 : days_reg <= DI;
a_reg[7] <= 1; 8'h08 : month_reg <= DI;
c_reg[4] <= 1; 8'h09 : year_reg <= DI;
// alarm 8'h0b : begin
if ((seconds_reg == seconds_alarm_reg) && (minutes_reg == minutes_alarm_reg) && (hours_reg == hours_alarm_reg)) c_reg[5] <= 1'b1; b_reg <= DI;
if (b_reg[2] == 1'b0) begin // BCD to BIN convertion
if (DI[4] == 1'b0) leap_reg <= DI[1:0];
else leap_reg <= {~DI[1], DI[0]};
end
else begin
leap_reg <= DI[1:0];
end
end
8'h0c : KEYSCANCODE_CLR <= DI[0];
8'hf? : keyrd_enable <= (DI == 8'd2)? 1'b1 : 1'b0;
endcase
end
if (~b_reg[2]) begin if (RESET) begin
// DM binary-coded-decimal (BCD) data mode a_reg <= 8'b00100110;
if (seconds_reg[3:0] != 9) seconds_reg[3:0] <= seconds_reg[3:0] + 1'd1; c_reg <= 0;
else begin end
seconds_reg[3:0] <= 0; else if (~b_reg[7] & ENA) begin
if (seconds_reg[6:4] != 5) seconds_reg[6:4] <= seconds_reg[6:4] + 1'd1; if (pre_scaler) begin
else begin pre_scaler <= pre_scaler - 1'd1;
seconds_reg[6:4] <= 0; a_reg[7] <= 0;
if (minutes_reg[3:0] != 9) minutes_reg[3:0] <= minutes_reg[3:0] + 1'd1; end
else begin else begin
minutes_reg[3:0] <= 0; pre_scaler <= 437500; //(0.4375MHz)
if (minutes_reg[6:4] != 5) minutes_reg[6:4] <= minutes_reg[6:4] + 1'd1; a_reg[7] <= 1;
else begin c_reg[4] <= 1;
minutes_reg[6:4] <= 0; // alarm
if (hours_reg[3:0] == 9) begin if ((seconds_reg == seconds_alarm_reg) && (minutes_reg == minutes_alarm_reg) && (hours_reg == hours_alarm_reg)) c_reg[5] <= 1'b1;
hours_reg[3:0] <= 0;
hours_reg[5:4] <= hours_reg[5:4] + 1'd1;
end
else if ({b_reg[1], hours_reg[7], hours_reg[4:0]} == 7'b0010010) begin
hours_reg[4:0] <= 1;
hours_reg[7] <= ~hours_reg[7];
end
else if (({b_reg[1], hours_reg[7], hours_reg[4:0]} != 7'b0110010) &&
({b_reg[1], hours_reg[5:0]} != 7'b1100011)) hours_reg[3:0] <= hours_reg[3:0] + 1'd1;
else begin
if (~b_reg[1]) hours_reg[7:0] <= 1;
else hours_reg[5:0] <= 0;
if (weeks_reg[2:0] != 7) weeks_reg[2:0] <= weeks_reg[2:0] + 1'd1; if (~b_reg[2]) begin
else weeks_reg[2:0] <= 1; // DM binary-coded-decimal (BCD) data mode
if (seconds_reg[3:0] != 9) seconds_reg[3:0] <= seconds_reg[3:0] + 1'd1;
else begin
seconds_reg[3:0] <= 0;
if (seconds_reg[6:4] != 5) seconds_reg[6:4] <= seconds_reg[6:4] + 1'd1;
else begin
seconds_reg[6:4] <= 0;
if (minutes_reg[3:0] != 9) minutes_reg[3:0] <= minutes_reg[3:0] + 1'd1;
else begin
minutes_reg[3:0] <= 0;
if (minutes_reg[6:4] != 5) minutes_reg[6:4] <= minutes_reg[6:4] + 1'd1;
else begin
minutes_reg[6:4] <= 0;
if (hours_reg[3:0] == 9) begin
hours_reg[3:0] <= 0;
hours_reg[5:4] <= hours_reg[5:4] + 1'd1;
end
else if ({b_reg[1], hours_reg[7], hours_reg[4:0]} == 7'b0010010) begin
hours_reg[4:0] <= 1;
hours_reg[7] <= ~hours_reg[7];
end
else if (({b_reg[1], hours_reg[7], hours_reg[4:0]} != 7'b0110010) &&
({b_reg[1], hours_reg[5:0]} != 7'b1100011)) hours_reg[3:0] <= hours_reg[3:0] + 1'd1;
else begin
if (~b_reg[1]) hours_reg[7:0] <= 1;
else hours_reg[5:0] <= 0;
if (({month_reg, days_reg, leap_reg} == {16'h0228, 2'b01}) || if (weeks_reg[2:0] != 7) weeks_reg[2:0] <= weeks_reg[2:0] + 1'd1;
({month_reg, days_reg, leap_reg} == {16'h0228, 2'b10}) || else weeks_reg[2:0] <= 1;
({month_reg, days_reg, leap_reg} == {16'h0228, 2'b11}) ||
({month_reg, days_reg, leap_reg} == {16'h0229, 2'b00}) || if (({month_reg, days_reg, leap_reg} == {16'h0228, 2'b01}) ||
({month_reg, days_reg} == 16'h0430) || ({month_reg, days_reg, leap_reg} == {16'h0228, 2'b10}) ||
({month_reg, days_reg} == 16'h0630) || ({month_reg, days_reg, leap_reg} == {16'h0228, 2'b11}) ||
({month_reg, days_reg} == 16'h0930) || ({month_reg, days_reg, leap_reg} == {16'h0229, 2'b00}) ||
({month_reg, days_reg} == 16'h1130) || ({month_reg, days_reg} == 16'h0430) ||
(days_reg == 8'h31)) begin ({month_reg, days_reg} == 16'h0630) ||
({month_reg, days_reg} == 16'h0930) ||
days_reg[5:0] <= 1; ({month_reg, days_reg} == 16'h1130) ||
if (month_reg[3:0] == 9) month_reg[4:0] <= 'h10; (days_reg == 8'h31)) begin
else if (month_reg[4:0] != 'h12) month_reg[3:0] <= month_reg[3:0] + 1'd1;
else begin days_reg[5:0] <= 1;
month_reg[4:0] <= 1; if (month_reg[3:0] == 9) month_reg[4:0] <= 'h10;
leap_reg[1:0] <= leap_reg[1:0] + 1'd1; else if (month_reg[4:0] != 'h12) month_reg[3:0] <= month_reg[3:0] + 1'd1;
if (year_reg[3:0] != 9) year_reg[3:0] <= year_reg[3:0] + 1'd1; else begin
else begin month_reg[4:0] <= 1;
year_reg[3:0] <= 0; leap_reg[1:0] <= leap_reg[1:0] + 1'd1;
if (year_reg[7:4] != 9) year_reg[7:4] <= year_reg[7:4] + 1'd1; if (year_reg[3:0] != 9) year_reg[3:0] <= year_reg[3:0] + 1'd1;
else year_reg[7:4] <= 0; else begin
end year_reg[3:0] <= 0;
end if (year_reg[7:4] != 9) year_reg[7:4] <= year_reg[7:4] + 1'd1;
end else year_reg[7:4] <= 0;
else if (days_reg[3:0] != 9) days_reg[3:0] <= days_reg[3:0] + 1'd1; end
else begin end
days_reg[3:0] <= 0; end
days_reg[5:4] <= days_reg[5:4] + 1'd1; else if (days_reg[3:0] != 9) days_reg[3:0] <= days_reg[3:0] + 1'd1;
end else begin
end days_reg[3:0] <= 0;
end days_reg[5:4] <= days_reg[5:4] + 1'd1;
end end
end end
end end
end else begin end
// DM binary data mode end
if (seconds_reg != 8'h3B) seconds_reg <= seconds_reg + 1'd1; end
else begin end
seconds_reg <= 0; else begin
if (minutes_reg != 8'h3B) minutes_reg <= minutes_reg + 1'd1; // DM binary data mode
else begin if (seconds_reg != 8'h3B) seconds_reg <= seconds_reg + 1'd1;
minutes_reg <= 0; else begin
if ({b_reg[1], hours_reg[7], hours_reg[3:0]} == 6'b001100) hours_reg[7:0] <= 8'b10000001; seconds_reg <= 0;
else if (({b_reg[1], hours_reg[7], hours_reg[3:0]} != 6'b011100) & ({b_reg[1], hours_reg[4:0]} != 6'b110111)) hours_reg[4:0] <= hours_reg[4:0] + 1'd1; if (minutes_reg != 8'h3B) minutes_reg <= minutes_reg + 1'd1;
else begin else begin
if (b_reg[1] == 1'b0) hours_reg[7:0] <= 1; minutes_reg <= 0;
else hours_reg <= 0; if ({b_reg[1], hours_reg[7], hours_reg[3:0]} == 6'b001100) hours_reg[7:0] <= 8'b10000001;
else if (({b_reg[1], hours_reg[7], hours_reg[3:0]} != 6'b011100) & ({b_reg[1], hours_reg[4:0]} != 6'b110111)) hours_reg[4:0] <= hours_reg[4:0] + 1'd1;
if (weeks_reg != 7) weeks_reg <= weeks_reg + 1'd1; else begin
else weeks_reg <= 1; // Sunday = 1 if (b_reg[1] == 1'b0) hours_reg[7:0] <= 1;
else hours_reg <= 0;
if (({month_reg, days_reg, leap_reg} == {16'h021C, 2'b01}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b10}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b11}) | ({month_reg, days_reg, leap_reg} == {16'h021D, 2'b00}) | ({month_reg, days_reg} == 16'h041E) | ({month_reg, days_reg} == 16'h061E) | ({month_reg, days_reg} == 16'h091E) | ({month_reg, days_reg} == 16'h0B1E) | (days_reg == 8'h1F)) begin
days_reg <= 1; if (weeks_reg != 7) weeks_reg <= weeks_reg + 1'd1;
if (month_reg != 8'h0C) month_reg <= month_reg + 1'd1; else weeks_reg <= 1; // Sunday = 1
else begin
month_reg <= 1; if (({month_reg, days_reg, leap_reg} == {16'h021C, 2'b01}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b10}) | ({month_reg, days_reg, leap_reg} == {16'h021C, 2'b11}) | ({month_reg, days_reg, leap_reg} == {16'h021D, 2'b00}) | ({month_reg, days_reg} == 16'h041E) | ({month_reg, days_reg} == 16'h061E) | ({month_reg, days_reg} == 16'h091E) | ({month_reg, days_reg} == 16'h0B1E) | (days_reg == 8'h1F)) begin
leap_reg[1:0] <= leap_reg[1:0] + 1'd1; days_reg <= 1;
if (year_reg != 8'h63) year_reg <= year_reg + 1'd1; if (month_reg != 8'h0C) month_reg <= month_reg + 1'd1;
else year_reg <= 0; else begin
end month_reg <= 1;
end else days_reg <= days_reg + 1'd1; leap_reg[1:0] <= leap_reg[1:0] + 1'd1;
end if (year_reg != 8'h63) year_reg <= year_reg + 1'd1;
end else year_reg <= 0;
end end
end end else days_reg <= days_reg + 1'd1;
end end
end end
end
end
end
end
end end
// 50 Bytes of General Purpose RAM // 50 Bytes of General Purpose RAM
dpram #(.DATAWIDTH(8), .ADDRWIDTH(8), .MEM_INIT_FILE("rtl/periph/CMOS.mif")) CMOS dpram #(.DATAWIDTH(8), .ADDRWIDTH(8), .MEM_INIT_FILE("rtl/periph/CMOS.mif")) CMOS
( (
.clock (CLK), .clock (CLK),
.address_a (A), .address_a (A),
.data_a (DI), .data_a (DI),
.wren_a (WR & CS), .wren_a (WR & CS),
.q_a (CMOS_Dout), .q_a (CMOS_Dout),
.address_b (loader_A), .address_b (loader_A),
.data_b (loader_DI), .data_b (loader_DI),
.wren_b (loader_WR), .wren_b (loader_WR),
.q_b (loader_DO) .q_b (loader_DO)
); );
endmodule endmodule

View File

@ -926,6 +926,8 @@ module tsconf
// PS/2 Keyboard // PS/2 Keyboard
wire key_reset; wire key_reset;
wire [7:0] key_scancode; wire [7:0] key_scancode;
wire key_scancode_ack;
wire key_scancode_clr;
keyboard keyboard keyboard keyboard
( (
@ -935,6 +937,8 @@ module tsconf
.keyb(kbd_port_data), .keyb(kbd_port_data),
.key_reset(key_reset), .key_reset(key_reset),
.scancode(key_scancode), .scancode(key_scancode),
.scancode_ack(key_scancode_ack),
.scancode_clr(key_scancode_clr),
.ps2_key(PS2_KEY), .ps2_key(PS2_KEY),
.cfg_joystick1(CFG_JOYSTICK1), .cfg_joystick1(CFG_JOYSTICK1),
.cfg_joystick2(CFG_JOYSTICK2), .cfg_joystick2(CFG_JOYSTICK2),
@ -973,6 +977,9 @@ module tsconf
.CS(1), .CS(1),
.RTC(RTC), .RTC(RTC),
.KEYSCANCODE(key_scancode), .KEYSCANCODE(key_scancode),
.KEYSCANCODE_ACK(key_scancode_ack),
.KEYSCANCODE_CLR(key_scancode_clr),
.RD(wait_start_gluclock & ~rd_n),
.WR(wait_start_gluclock & ~wr_n), .WR(wait_start_gluclock & ~wr_n),
.A(wait_addr), .A(wait_addr),
.DI(d), .DI(d),