diff --git a/rtl/periph/keyboard.v b/rtl/periph/keyboard.v index b7b9656..fee079d 100644 --- a/rtl/periph/keyboard.v +++ b/rtl/periph/keyboard.v @@ -6,6 +6,8 @@ module keyboard output [4:0] keyb, output reg key_reset, output reg [7:0] scancode, + input scancode_ack, + input scancode_clr, input [10:0] ps2_key, input [1:0] cfg_joystick1, input [1:0] cfg_joystick2, @@ -69,76 +71,76 @@ always @(posedge clk) begin case (cfg_joystick1) 2'b01: begin // Sinclair 1 case (joys_chn) - 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h3d}; // Right | 7 - 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h36}; // Left | 6 - 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h3e}; // Down | 8 - 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 - 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 - 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h32}; // Fire 4 | b + 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h3d}; // Right | 7 + 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h36}; // Left | 6 + 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h3e}; // Down | 8 + 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 + 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 + 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h32}; // Fire 4 | b endcase end 2'b10: begin // Sinclair 2 case (joys_chn) - 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h1e}; // Right | 2 - 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h16}; // Left | 1 - 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h26}; // Down | 3 - 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 - 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 - 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h21}; // Fire 4 | c + 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h1e}; // Right | 2 + 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h16}; // Left | 1 + 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h26}; // Down | 3 + 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 + 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 + 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h21}; // Fire 4 | c endcase end 2'b11: begin // Cursor case (joys_chn) - 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h74}; // Right | Right - 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h6b}; // Left | Left - 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h72}; // Down | Down - 3: {strobe, press, code} <= {1'b1, joys[3 ], 9'h75}; // Up | Up - 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 - 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 + 0: {strobe, press, code} <= {1'b1, joys[0 ], 9'h174}; // Right | Right + 1: {strobe, press, code} <= {1'b1, joys[1 ], 9'h16b}; // Left | Left + 2: {strobe, press, code} <= {1'b1, joys[2 ], 9'h172}; // Down | Down + 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 + 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 + 7: {strobe, press, code} <= {1'b1, joys[7 ], 9'h76}; // Fire 4 | Esc endcase end endcase case (cfg_joystick2) 2'b01: begin // Sinclair 1 case (joys_chn) - 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h3d}; // Right | 7 - 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h36}; // Left | 6 - 10: {strobe, press, code} <= {1'b1, joys[10], 9'h3e}; // Down | 8 - 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 - 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 - 15: {strobe, press, code} <= {1'b1, joys[15], 9'h32}; // Fire 4 | b + 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h3d}; // Right | 7 + 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h36}; // Left | 6 + 10: {strobe, press, code} <= {1'b1, joys[10], 9'h3e}; // Down | 8 + 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 + 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 + 15: {strobe, press, code} <= {1'b1, joys[15], 9'h32}; // Fire 4 | b endcase end 2'b10: begin // Sinclair 2 case (joys_chn) - 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h1e}; // Right | 2 - 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h16}; // Left | 1 - 10: {strobe, press, code} <= {1'b1, joys[10], 9'h26}; // Down | 3 - 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 - 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 - 15: {strobe, press, code} <= {1'b1, joys[15], 9'h21}; // Fire 4 | c + 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h1e}; // Right | 2 + 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h16}; // Left | 1 + 10: {strobe, press, code} <= {1'b1, joys[10], 9'h26}; // Down | 3 + 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 + 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 + 15: {strobe, press, code} <= {1'b1, joys[15], 9'h21}; // Fire 4 | c endcase end 2'b11: begin // Cursor case (joys_chn) - 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h74}; // Right | Right - 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h6b}; // Left | Left - 10: {strobe, press, code} <= {1'b1, joys[10], 9'h72}; // Down | Down - 11: {strobe, press, code} <= {1'b1, joys[11], 9'h75}; // Up | Up - 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 - 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 + 8: {strobe, press, code} <= {1'b1, joys[8 ], 9'h174}; // Right | Right + 9: {strobe, press, code} <= {1'b1, joys[9 ], 9'h16b}; // Left | Left + 10: {strobe, press, code} <= {1'b1, joys[10], 9'h172}; // Down | Down + 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 + 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 + 15: {strobe, press, code} <= {1'b1, joys[15], 9'h76}; // Fire 4 | Esc endcase end endcase @@ -157,14 +159,9 @@ always @(posedge clk or posedge reset) begin keys[6] <= 5'b11111; keys[7] <= 5'b11111; key_reset <= 0; - scancode <= 0; end else begin if (strobe) begin - if (press) - scancode <= code[7:0]; - else - scancode <= 8'hFF; case (code[7:0]) 8'h12: keys[0][0] <= ~press; // Left 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 + +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 diff --git a/rtl/periph/mc146818a.v b/rtl/periph/mc146818a.v index ac97a7d..e8ae66f 100644 --- a/rtl/periph/mc146818a.v +++ b/rtl/periph/mc146818a.v @@ -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 ( - input RESET, - input CLK, - input ENA, - input CS, + input RESET, + input CLK, + input ENA, + input CS, - input [64:0] RTC, - input [7:0] KEYSCANCODE, + input [64:0] RTC, + input [7:0] KEYSCANCODE, + output reg KEYSCANCODE_ACK, + output reg KEYSCANCODE_CLR, - input WR, - input [7:0] A, - input [7:0] DI, - output [7:0] DO, + input RD, + input WR, + input [7:0] A, + input [7:0] DI, + output reg [7:0] DO, - input loader_WR, - input [7:0] loader_A, - input [7:0] loader_DI, - output [7:0] loader_DO + input loader_WR, + input [7:0] loader_A, + input [7:0] loader_DI, + output [7:0] loader_DO ); - + reg [18:0] pre_scaler =0; reg [1:0] leap_reg =0; -reg [7:0] seconds_reg =0; // 00 -reg [7:0] seconds_alarm_reg =0; // 01 -reg [7:0] minutes_reg =0; // 02 -reg [7:0] minutes_alarm_reg = 0;// 03 -reg [7:0] hours_reg =0; // 04 -reg [7:0] hours_alarm_reg ='hff;// 05 -reg [7:0] weeks_reg = 1; // 06 -reg [7:0] days_reg = 1; // 07 -reg [7:0] month_reg = 1; // 08 -reg [7:0] year_reg = 0; // 09 -reg [7:0] a_reg; // 0A -reg [7:0] b_reg = 8'b00000010; // 0B -reg [7:0] c_reg; // 0C +reg [7:0] seconds_reg =0; // 00 +reg [7:0] seconds_alarm_reg =0; // 01 +reg [7:0] minutes_reg =0; // 02 +reg [7:0] minutes_alarm_reg = 0; // 03 +reg [7:0] hours_reg =0; // 04 +reg [7:0] hours_alarm_reg ='hff; // 05 +reg [7:0] weeks_reg = 1; // 06 +reg [7:0] days_reg = 1; // 07 +reg [7:0] month_reg = 1; // 08 +reg [7:0] year_reg = 0; // 09 +reg [7:0] a_reg; // 0A +reg [7:0] b_reg = 8'b00000010; // 0B +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; -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; - -always @(*) begin - case (A[7:0]) - 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 + 8'hf? : DO <= KEYSCANCODE; + default: DO <= CMOS_Dout; + endcase + end end + always @(posedge CLK) begin - if (RTC[62] && !b_reg[7]) begin - 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 + KEYSCANCODE_CLR <= 1'b0; - if (RESET) b_reg <= 8'b00000010; - else if (WR & CS) begin - /* - case (A[7:0]) - 0 : seconds_reg <= DI; - 1 : seconds_alarm_reg <= DI; - 2 : minutes_reg <= DI; - 3 : minutes_alarm_reg <= DI; - 4 : hours_reg <= DI; - 5 : hours_alarm_reg <= DI; - 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 (RTC[62] && !b_reg[7]) begin + 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) begin - a_reg <= 8'b00100110; - c_reg <= 0; - end - else if (~b_reg[7] & ENA) begin - if (pre_scaler) begin - pre_scaler <= pre_scaler - 1'd1; - a_reg[7] <= 0; - end - else begin - pre_scaler <= 437500; //(0.4375MHz) - a_reg[7] <= 1; - c_reg[4] <= 1; - // alarm - if ((seconds_reg == seconds_alarm_reg) && (minutes_reg == minutes_alarm_reg) && (hours_reg == hours_alarm_reg)) c_reg[5] <= 1'b1; + if (RESET) b_reg <= 8'b00000010; + else if (WR & CS) begin + casez (A[7:0]) + 8'h00 : seconds_reg <= DI; + 8'h01 : seconds_alarm_reg <= DI; + 8'h02 : minutes_reg <= DI; + 8'h03 : minutes_alarm_reg <= DI; + 8'h04 : hours_reg <= DI; + 8'h05 : hours_alarm_reg <= DI; + 8'h06 : weeks_reg <= DI; + 8'h07 : days_reg <= DI; + 8'h08 : month_reg <= DI; + 8'h09 : year_reg <= DI; + 8'h0b : 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 + 8'h0c : KEYSCANCODE_CLR <= DI[0]; + 8'hf? : keyrd_enable <= (DI == 8'd2)? 1'b1 : 1'b0; + endcase + end - if (~b_reg[2]) begin - // 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 (RESET) begin + a_reg <= 8'b00100110; + c_reg <= 0; + end + else if (~b_reg[7] & ENA) begin + if (pre_scaler) begin + pre_scaler <= pre_scaler - 1'd1; + a_reg[7] <= 0; + end + else begin + pre_scaler <= 437500; //(0.4375MHz) + a_reg[7] <= 1; + c_reg[4] <= 1; + // alarm + if ((seconds_reg == seconds_alarm_reg) && (minutes_reg == minutes_alarm_reg) && (hours_reg == hours_alarm_reg)) c_reg[5] <= 1'b1; - if (weeks_reg[2:0] != 7) weeks_reg[2:0] <= weeks_reg[2:0] + 1'd1; - else weeks_reg[2:0] <= 1; + if (~b_reg[2]) begin + // 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}) || - ({month_reg, days_reg, leap_reg} == {16'h0228, 2'b10}) || - ({month_reg, days_reg, leap_reg} == {16'h0228, 2'b11}) || - ({month_reg, days_reg, leap_reg} == {16'h0229, 2'b00}) || - ({month_reg, days_reg} == 16'h0430) || - ({month_reg, days_reg} == 16'h0630) || - ({month_reg, days_reg} == 16'h0930) || - ({month_reg, days_reg} == 16'h1130) || - (days_reg == 8'h31)) begin - - days_reg[5:0] <= 1; - if (month_reg[3:0] == 9) month_reg[4:0] <= 'h10; - else if (month_reg[4:0] != 'h12) month_reg[3:0] <= month_reg[3:0] + 1'd1; - else begin - month_reg[4:0] <= 1; - leap_reg[1:0] <= leap_reg[1:0] + 1'd1; - if (year_reg[3:0] != 9) year_reg[3:0] <= year_reg[3:0] + 1'd1; - else begin - year_reg[3:0] <= 0; - if (year_reg[7:4] != 9) year_reg[7:4] <= year_reg[7:4] + 1'd1; - else year_reg[7:4] <= 0; - end - end - end - else if (days_reg[3:0] != 9) days_reg[3:0] <= days_reg[3:0] + 1'd1; - else begin - days_reg[3:0] <= 0; - days_reg[5:4] <= days_reg[5:4] + 1'd1; - end - end - end - end - end - end - end else begin - // DM binary data mode - if (seconds_reg != 8'h3B) seconds_reg <= seconds_reg + 1'd1; - else begin - seconds_reg <= 0; - if (minutes_reg != 8'h3B) minutes_reg <= minutes_reg + 1'd1; - else begin - minutes_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; - else begin - if (b_reg[1] == 1'b0) hours_reg[7:0] <= 1; - else hours_reg <= 0; - - if (weeks_reg != 7) weeks_reg <= weeks_reg + 1'd1; - else weeks_reg <= 1; // Sunday = 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 - days_reg <= 1; - if (month_reg != 8'h0C) month_reg <= month_reg + 1'd1; - else begin - month_reg <= 1; - leap_reg[1:0] <= leap_reg[1:0] + 1'd1; - if (year_reg != 8'h63) year_reg <= year_reg + 1'd1; - else year_reg <= 0; - end - end else days_reg <= days_reg + 1'd1; - end - end - end - end - end - end + if (weeks_reg[2:0] != 7) weeks_reg[2:0] <= weeks_reg[2:0] + 1'd1; + else weeks_reg[2:0] <= 1; + + if (({month_reg, days_reg, leap_reg} == {16'h0228, 2'b01}) || + ({month_reg, days_reg, leap_reg} == {16'h0228, 2'b10}) || + ({month_reg, days_reg, leap_reg} == {16'h0228, 2'b11}) || + ({month_reg, days_reg, leap_reg} == {16'h0229, 2'b00}) || + ({month_reg, days_reg} == 16'h0430) || + ({month_reg, days_reg} == 16'h0630) || + ({month_reg, days_reg} == 16'h0930) || + ({month_reg, days_reg} == 16'h1130) || + (days_reg == 8'h31)) begin + + days_reg[5:0] <= 1; + if (month_reg[3:0] == 9) month_reg[4:0] <= 'h10; + else if (month_reg[4:0] != 'h12) month_reg[3:0] <= month_reg[3:0] + 1'd1; + else begin + month_reg[4:0] <= 1; + leap_reg[1:0] <= leap_reg[1:0] + 1'd1; + if (year_reg[3:0] != 9) year_reg[3:0] <= year_reg[3:0] + 1'd1; + else begin + year_reg[3:0] <= 0; + if (year_reg[7:4] != 9) year_reg[7:4] <= year_reg[7:4] + 1'd1; + else year_reg[7:4] <= 0; + end + end + end + else if (days_reg[3:0] != 9) days_reg[3:0] <= days_reg[3:0] + 1'd1; + else begin + days_reg[3:0] <= 0; + days_reg[5:4] <= days_reg[5:4] + 1'd1; + end + end + end + end + end + end + end + else begin + // DM binary data mode + if (seconds_reg != 8'h3B) seconds_reg <= seconds_reg + 1'd1; + else begin + seconds_reg <= 0; + if (minutes_reg != 8'h3B) minutes_reg <= minutes_reg + 1'd1; + else begin + minutes_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; + else begin + if (b_reg[1] == 1'b0) hours_reg[7:0] <= 1; + else hours_reg <= 0; + + if (weeks_reg != 7) weeks_reg <= weeks_reg + 1'd1; + else weeks_reg <= 1; // Sunday = 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 + days_reg <= 1; + if (month_reg != 8'h0C) month_reg <= month_reg + 1'd1; + else begin + month_reg <= 1; + leap_reg[1:0] <= leap_reg[1:0] + 1'd1; + if (year_reg != 8'h63) year_reg <= year_reg + 1'd1; + else year_reg <= 0; + end + end else days_reg <= days_reg + 1'd1; + 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 ( - .clock (CLK), - .address_a (A), - .data_a (DI), - .wren_a (WR & CS), - .q_a (CMOS_Dout), - .address_b (loader_A), - .data_b (loader_DI), - .wren_b (loader_WR), - .q_b (loader_DO) + .clock (CLK), + .address_a (A), + .data_a (DI), + .wren_a (WR & CS), + .q_a (CMOS_Dout), + .address_b (loader_A), + .data_b (loader_DI), + .wren_b (loader_WR), + .q_b (loader_DO) ); - + endmodule diff --git a/rtl/tsconf.v b/rtl/tsconf.v index cfaba4c..7e1e0f5 100644 --- a/rtl/tsconf.v +++ b/rtl/tsconf.v @@ -926,6 +926,8 @@ module tsconf // PS/2 Keyboard wire key_reset; wire [7:0] key_scancode; + wire key_scancode_ack; + wire key_scancode_clr; keyboard keyboard ( @@ -935,6 +937,8 @@ module tsconf .keyb(kbd_port_data), .key_reset(key_reset), .scancode(key_scancode), + .scancode_ack(key_scancode_ack), + .scancode_clr(key_scancode_clr), .ps2_key(PS2_KEY), .cfg_joystick1(CFG_JOYSTICK1), .cfg_joystick2(CFG_JOYSTICK2), @@ -973,6 +977,9 @@ module tsconf .CS(1), .RTC(RTC), .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), .A(wait_addr), .DI(d),