mirror of
https://github.com/UzixLS/zx-sizif-xxs.git
synced 2025-07-19 07:11:28 +03:00
ps2: handle more buttons, add kempston
This commit is contained in:
@ -5,6 +5,8 @@ module ports(
|
||||
input en_128k,
|
||||
input en_plus3,
|
||||
input en_profi,
|
||||
input en_kempston,
|
||||
input en_sinclair,
|
||||
|
||||
cpu_bus bus,
|
||||
output [7:0] d_out,
|
||||
@ -16,9 +18,8 @@ module ports(
|
||||
input [7:0] attr_next,
|
||||
input [4:0] kd,
|
||||
input [7:0] kempston_data,
|
||||
input joy_sinclair,
|
||||
input magic_active_next,
|
||||
input sd_miso_tape_in,
|
||||
input tape_in,
|
||||
|
||||
output reg tape_out,
|
||||
output reg beeper,
|
||||
@ -54,7 +55,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
|
||||
reg [4:0] kd0;
|
||||
wire [7:0] port_fe_data = {~magic_active_next, sd_miso_tape_in, 1'b1, kd0};
|
||||
wire [7:0] port_fe_data = {~magic_active_next, tape_in, 1'b1, kd0};
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
beeper <= 0;
|
||||
@ -72,7 +73,7 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
kd0 <= 5'b11111;
|
||||
end
|
||||
else if (joy_sinclair) begin
|
||||
else if (en_sinclair) begin
|
||||
kd0 <= kd
|
||||
& (bus.a[12] == 0? {~kempston_data[1], ~kempston_data[0], ~kempston_data[2], ~kempston_data[3], ~kempston_data[4]} : 5'b11111) // 6-0 keys
|
||||
& (bus.a[15] == 0? {1'b1, ~kempston_data[6], ~kempston_data[5], 2'b11} : 5'b11111 ) ; // b-space keys
|
||||
@ -130,10 +131,21 @@ always @(posedge clk28 or negedge rst_n) begin
|
||||
end
|
||||
|
||||
|
||||
/* KEMPSTON */
|
||||
reg kempston_rd;
|
||||
always @(posedge clk28 or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
kempston_rd <= 0;
|
||||
else
|
||||
kempston_rd <= en_kempston && bus.ioreq && bus.rd && bus.a[7:5] == 3'b000;
|
||||
end
|
||||
|
||||
|
||||
/* BUS CONTROLLER */
|
||||
assign d_out_active = port_fe_rd | port_ff_rd;
|
||||
assign d_out_active = port_fe_rd | port_ff_rd | kempston_rd;
|
||||
|
||||
assign d_out =
|
||||
kempston_rd? kempston_data :
|
||||
port_fe_rd? port_fe_data :
|
||||
port_ff_data ;
|
||||
|
||||
|
179
fpga/rtl/ps2.v
179
fpga/rtl/ps2.v
@ -14,7 +14,13 @@ module ps2#(
|
||||
input [7:0] zxkb_addr,
|
||||
output [4:0] zxkb_data,
|
||||
output reg key_magic,
|
||||
output reg key_reset
|
||||
output reg key_reset,
|
||||
output reg key_pause,
|
||||
output reg joy_up,
|
||||
output reg joy_down,
|
||||
output reg joy_left,
|
||||
output reg joy_right,
|
||||
output reg joy_fire
|
||||
);
|
||||
|
||||
|
||||
@ -49,90 +55,123 @@ ps2_rxtx #(.CLK_FREQ(CLK_FREQ)) ps2_rxtx0(
|
||||
reg is_press;
|
||||
reg is_ext;
|
||||
reg [4:0] zxkb [0:7];
|
||||
reg key_ctrl, key_alt, key_del;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
integer i;
|
||||
for (i = 0; i < 8; i = i + 1)
|
||||
zxkb[i] <= 0;
|
||||
is_press <= 0;
|
||||
is_press <= 1'b1;
|
||||
is_ext <= 0;
|
||||
key_magic <= 0;
|
||||
key_reset <= 0;
|
||||
key_pause <= 0;
|
||||
key_ctrl <= 0;
|
||||
key_alt <= 0;
|
||||
key_del <= 0;
|
||||
joy_up <= 0;
|
||||
joy_down <= 0;
|
||||
joy_left <= 0;
|
||||
joy_right <= 0;
|
||||
joy_fire <= 0;
|
||||
end
|
||||
else begin
|
||||
if (rxerr) begin
|
||||
is_press <= 0;
|
||||
is_ext <= 0;
|
||||
end
|
||||
else if (rxdone) begin
|
||||
if (rxdone) begin
|
||||
case ({is_ext, rxbyte})
|
||||
`PS2_A: zxkb[1][0] <= is_press;
|
||||
`PS2_B: zxkb[7][4] <= is_press;
|
||||
`PS2_C: zxkb[0][3] <= is_press;
|
||||
`PS2_D: zxkb[1][2] <= is_press;
|
||||
`PS2_E: zxkb[2][2] <= is_press;
|
||||
`PS2_F: zxkb[1][3] <= is_press;
|
||||
`PS2_G: zxkb[1][4] <= is_press;
|
||||
`PS2_H: zxkb[6][4] <= is_press;
|
||||
`PS2_I: zxkb[5][2] <= is_press;
|
||||
`PS2_J: zxkb[6][3] <= is_press;
|
||||
`PS2_K: zxkb[6][2] <= is_press;
|
||||
`PS2_L: zxkb[6][1] <= is_press;
|
||||
`PS2_M: zxkb[7][2] <= is_press;
|
||||
`PS2_N: zxkb[7][3] <= is_press;
|
||||
`PS2_O: zxkb[5][1] <= is_press;
|
||||
`PS2_P: zxkb[5][0] <= is_press;
|
||||
`PS2_Q: zxkb[2][0] <= is_press;
|
||||
`PS2_R: zxkb[2][3] <= is_press;
|
||||
`PS2_S: zxkb[1][1] <= is_press;
|
||||
`PS2_T: zxkb[2][4] <= is_press;
|
||||
`PS2_U: zxkb[5][3] <= is_press;
|
||||
`PS2_V: zxkb[0][4] <= is_press;
|
||||
`PS2_W: zxkb[2][1] <= is_press;
|
||||
`PS2_X: zxkb[0][2] <= is_press;
|
||||
`PS2_Y: zxkb[5][4] <= is_press;
|
||||
`PS2_Z: zxkb[0][1] <= is_press;
|
||||
`PS2_0: zxkb[4][0] <= is_press;
|
||||
`PS2_1: zxkb[3][0] <= is_press;
|
||||
`PS2_2: zxkb[3][1] <= is_press;
|
||||
`PS2_3: zxkb[3][2] <= is_press;
|
||||
`PS2_4: zxkb[3][3] <= is_press;
|
||||
`PS2_5: zxkb[3][4] <= is_press;
|
||||
`PS2_6: zxkb[4][4] <= is_press;
|
||||
`PS2_7: zxkb[4][3] <= is_press;
|
||||
`PS2_8: zxkb[4][2] <= is_press;
|
||||
`PS2_9: zxkb[4][1] <= is_press;
|
||||
`PS2_SPACE: zxkb[7][0] <= is_press;
|
||||
`PS2_ENTER: zxkb[6][0] <= is_press;
|
||||
|
||||
`PS2_L_SHIFT: zxkb[0][0] <= is_press;
|
||||
`PS2_R_SHIFT: zxkb[0][0] <= is_press;
|
||||
`PS2_L_CTRL: begin zxkb[7][1] <= is_press; key_ctrl <= is_press; end
|
||||
`PS2_R_CTRL: begin zxkb[7][1] <= is_press; key_ctrl <= is_press; end
|
||||
|
||||
`PS2_UP: begin zxkb[0][0] <= is_press; zxkb[4][3] <= is_press; end
|
||||
`PS2_DOWN: begin zxkb[0][0] <= is_press; zxkb[4][4] <= is_press; end
|
||||
`PS2_LEFT: begin zxkb[0][0] <= is_press; zxkb[3][4] <= is_press; end
|
||||
`PS2_RIGHT: begin zxkb[0][0] <= is_press; zxkb[4][2] <= is_press; end
|
||||
|
||||
`PS2_ESC: begin zxkb[0][0] <= is_press; zxkb[7][0] <= is_press; end
|
||||
`PS2_BACKSPACE: begin zxkb[0][0] <= is_press; zxkb[4][0] <= is_press; end
|
||||
`PS2_ACCENT: begin zxkb[7][1] <= is_press; zxkb[4][3] <= is_press; end
|
||||
`PS2_MINUS: begin zxkb[7][1] <= is_press; zxkb[6][3] <= is_press; end
|
||||
`PS2_EQUALS: begin zxkb[7][1] <= is_press; zxkb[6][1] <= is_press; end
|
||||
`PS2_BACK_SLASH:begin zxkb[7][1] <= is_press; zxkb[0][4] <= is_press; end
|
||||
`PS2_TAB: begin zxkb[0][0] <= is_press; zxkb[3][0] <= is_press; end
|
||||
`PS2_L_BRACKET: begin zxkb[7][1] <= is_press; zxkb[4][2] <= is_press; end
|
||||
`PS2_R_BRACKET: begin zxkb[7][1] <= is_press; zxkb[4][1] <= is_press; end
|
||||
`PS2_SEMICOLON: begin zxkb[7][1] <= is_press; zxkb[5][1] <= is_press; end
|
||||
`PS2_QUOTE: begin zxkb[7][1] <= is_press; zxkb[5][0] <= is_press; end
|
||||
`PS2_COMMA: begin zxkb[7][1] <= is_press; zxkb[7][3] <= is_press; end
|
||||
`PS2_PERIOD: begin zxkb[7][1] <= is_press; zxkb[7][2] <= is_press; end
|
||||
`PS2_SLASH: begin zxkb[7][1] <= is_press; zxkb[0][4] <= is_press; end
|
||||
`PS2_CAPS: begin zxkb[0][0] <= is_press; zxkb[3][1] <= is_press; end
|
||||
`PS2_PGUP: begin zxkb[0][0] <= is_press; zxkb[3][2] <= is_press; end
|
||||
`PS2_PGDN: begin zxkb[0][0] <= is_press; zxkb[3][3] <= is_press; end
|
||||
|
||||
`PS2_F5: key_magic <= is_press;
|
||||
`PS2_F11: key_pause <= 1'b0;
|
||||
`PS2_F12: key_pause <= 1'b1;
|
||||
`PS2_DELETE: key_del <= is_press;
|
||||
|
||||
`PS2_KP_8: joy_up <= is_press;
|
||||
`PS2_KP_2: joy_down <= is_press;
|
||||
`PS2_KP_4: joy_left <= is_press;
|
||||
`PS2_KP_6: joy_right <= is_press;
|
||||
`PS2_L_ALT: begin joy_fire <= is_press; key_alt <= is_press; end
|
||||
`PS2_R_ALT: begin joy_fire <= is_press; key_alt <= is_press; end
|
||||
endcase
|
||||
is_press <= rxbyte != 8'hF0;
|
||||
is_ext <= rxbyte == 8'hE0 || (rxbyte == 8'hF0 && is_ext);
|
||||
case ({is_ext, rxbyte})
|
||||
`PS2_A: zxkb[1][0] = is_press;
|
||||
`PS2_B: zxkb[7][4] = is_press;
|
||||
`PS2_C: zxkb[0][3] = is_press;
|
||||
`PS2_D: zxkb[1][2] = is_press;
|
||||
`PS2_E: zxkb[2][2] = is_press;
|
||||
`PS2_F: zxkb[1][3] = is_press;
|
||||
`PS2_G: zxkb[1][4] = is_press;
|
||||
`PS2_H: zxkb[6][4] = is_press;
|
||||
`PS2_I: zxkb[5][2] = is_press;
|
||||
`PS2_J: zxkb[6][3] = is_press;
|
||||
`PS2_K: zxkb[6][2] = is_press;
|
||||
`PS2_L: zxkb[6][1] = is_press;
|
||||
`PS2_M: zxkb[7][2] = is_press;
|
||||
`PS2_N: zxkb[7][3] = is_press;
|
||||
`PS2_O: zxkb[5][1] = is_press;
|
||||
`PS2_P: zxkb[5][0] = is_press;
|
||||
`PS2_Q: zxkb[2][0] = is_press;
|
||||
`PS2_R: zxkb[2][3] = is_press;
|
||||
`PS2_S: zxkb[1][1] = is_press;
|
||||
`PS2_T: zxkb[2][4] = is_press;
|
||||
`PS2_U: zxkb[5][3] = is_press;
|
||||
`PS2_V: zxkb[0][4] = is_press;
|
||||
`PS2_W: zxkb[2][1] = is_press;
|
||||
`PS2_X: zxkb[0][2] = is_press;
|
||||
`PS2_Y: zxkb[5][4] = is_press;
|
||||
`PS2_Z: zxkb[0][1] = is_press;
|
||||
`PS2_0: zxkb[4][0] = is_press;
|
||||
`PS2_1: zxkb[3][0] = is_press;
|
||||
`PS2_2: zxkb[3][1] = is_press;
|
||||
`PS2_3: zxkb[3][2] = is_press;
|
||||
`PS2_4: zxkb[3][3] = is_press;
|
||||
`PS2_5: zxkb[3][4] = is_press;
|
||||
`PS2_6: zxkb[4][4] = is_press;
|
||||
`PS2_7: zxkb[4][3] = is_press;
|
||||
`PS2_8: zxkb[4][2] = is_press;
|
||||
`PS2_9: zxkb[4][1] = is_press;
|
||||
|
||||
`PS2_SPACE: zxkb[7][0] = is_press;
|
||||
`PS2_ENTER: zxkb[6][0] = is_press;
|
||||
`PS2_ESC: begin zxkb[0][0] = is_press; zxkb[7][0] = is_press; end
|
||||
`PS2_BACKSPACE: begin zxkb[0][0] = is_press; zxkb[4][0] = is_press; end
|
||||
|
||||
`PS2_PERIOD: begin zxkb[7][1] = is_press; zxkb[7][2] = is_press; end
|
||||
`PS2_COMMA: begin zxkb[7][1] = is_press; zxkb[7][3] = is_press; end
|
||||
`PS2_SLASH: begin zxkb[7][1] = is_press; zxkb[0][4] = is_press; end
|
||||
`PS2_SEMICOLON: begin zxkb[7][1] = is_press; zxkb[5][1] = is_press; end
|
||||
`PS2_QUOTE: begin zxkb[7][1] = is_press; zxkb[5][0] = is_press; end
|
||||
|
||||
`PS2_UP: begin zxkb[0][0] = is_press; zxkb[4][3] = is_press; end
|
||||
`PS2_DOWN: begin zxkb[0][0] = is_press; zxkb[4][4] = is_press; end
|
||||
`PS2_LEFT: begin zxkb[0][0] = is_press; zxkb[3][4] = is_press; end
|
||||
`PS2_RIGHT: begin zxkb[0][0] = is_press; zxkb[4][2] = is_press; end
|
||||
|
||||
`PS2_L_SHIFT: zxkb[7][1] = is_press;
|
||||
`PS2_R_SHIFT: zxkb[7][1] = is_press;
|
||||
`PS2_L_CTRL: zxkb[0][0] = is_press;
|
||||
`PS2_R_CTRL: zxkb[0][0] = is_press;
|
||||
|
||||
`PS2_F5: key_magic = is_press;
|
||||
`PS2_F12: key_reset = is_press;
|
||||
endcase
|
||||
end
|
||||
else if (rxerr) begin
|
||||
is_press <= 1'b1;
|
||||
is_ext <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n)
|
||||
key_reset <= 0;
|
||||
else
|
||||
key_reset <= key_ctrl && key_alt && key_del;
|
||||
end
|
||||
|
||||
always @* begin
|
||||
zxkb_data <= ~(
|
||||
|
@ -51,8 +51,6 @@ pll pll0(.inclk0(clk_in), .c0(clk40), .c1(clk20), .locked(rst_n));
|
||||
timings_t timings;
|
||||
turbo_t turbo;
|
||||
wire clkwait;
|
||||
reg magic_beeper;
|
||||
wire pause = 0;
|
||||
|
||||
reg n_iorq_delayed;
|
||||
always @(posedge clk28)
|
||||
@ -71,12 +69,41 @@ always @* begin
|
||||
end
|
||||
|
||||
|
||||
/* KEYBOARD */
|
||||
reg ps2_clk_out, ps2_dat_out;
|
||||
reg [4:0] ps2_kd;
|
||||
reg key_magic, key_reset, pause;
|
||||
wire usrrst_n = ~key_reset;
|
||||
reg joy_up, joy_down, joy_left, joy_right, joy_fire;
|
||||
ps2 #(.CLK_FREQ(28_000_000)) ps2_0(
|
||||
.rst_n(rst_n),
|
||||
.clk(clk28),
|
||||
.ps2_clk_in(ps2_clk),
|
||||
.ps2_dat_in(ps2_data),
|
||||
.ps2_clk_out(ps2_clk_out),
|
||||
.ps2_dat_out(ps2_dat_out),
|
||||
.zxkb_addr(bus.a[15:8]),
|
||||
.zxkb_data(ps2_kd),
|
||||
.key_magic(key_magic),
|
||||
.key_reset(key_reset),
|
||||
.key_pause(pause),
|
||||
.joy_up(joy_up),
|
||||
.joy_down(joy_down),
|
||||
.joy_left(joy_left),
|
||||
.joy_right(joy_right),
|
||||
.joy_fire(joy_fire)
|
||||
);
|
||||
assign ps2_clk = (ps2_clk_out == 0)? 1'b0 : 1'bz;
|
||||
assign ps2_data = (ps2_dat_out == 0)? 1'b0 : 1'bz;
|
||||
|
||||
|
||||
/* SCREEN CONTROLLER */
|
||||
reg [2:0] border;
|
||||
reg up_en;
|
||||
reg [1:0] r, g, b;
|
||||
reg hsync;
|
||||
wire blink;
|
||||
reg magic_beeper;
|
||||
wire [2:0] screen_border = {border[2] ^ ~sd_cs, border[1] ^ magic_beeper, border[0] ^ (pause & blink)};
|
||||
wire screen_read, screen_load, screen_read_up;
|
||||
wire [14:0] screen_addr;
|
||||
@ -144,7 +171,7 @@ logic n_int_next;
|
||||
wire snow, clkcpu_ck;
|
||||
wire init_done;
|
||||
cpucontrol cpucontrol0(
|
||||
.rst_n(rst_n),
|
||||
.rst_n(rst_n & usrrst_n),
|
||||
.clk28(clk28),
|
||||
.clk14(clk14),
|
||||
.clk7(clk7),
|
||||
@ -175,33 +202,13 @@ cpucontrol cpucontrol0(
|
||||
);
|
||||
|
||||
|
||||
/* KEYBOARD */
|
||||
reg ps2_clk_out, ps2_dat_out;
|
||||
reg [4:0] ps2_kd;
|
||||
reg key_magic, key_reset;
|
||||
ps2 #(.CLK_FREQ(28_000_000)) ps2_0 (
|
||||
.rst_n(rst_n),
|
||||
.clk(clk28),
|
||||
.ps2_clk_in(ps2_clk),
|
||||
.ps2_dat_in(ps2_data),
|
||||
.ps2_clk_out(ps2_clk_out),
|
||||
.ps2_dat_out(ps2_dat_out),
|
||||
.zxkb_addr(bus.a[15:8]),
|
||||
.zxkb_data(ps2_kd),
|
||||
.key_magic(key_magic),
|
||||
.key_reset(key_reset)
|
||||
);
|
||||
assign ps2_clk = (ps2_clk_out == 0)? 1'b0 : 1'bz;
|
||||
assign ps2_data = (ps2_dat_out == 0)? 1'b0 : 1'bz;
|
||||
|
||||
|
||||
/* MAGIC */
|
||||
reg magic_mode, magic_map;
|
||||
wire magic_active_next;
|
||||
reg n_nmi0;
|
||||
reg extlock, joy_sinclair, rom_plus3, rom_alt48, ay_abc, ay_mono;
|
||||
magic magic0(
|
||||
.rst_n(rst_n),
|
||||
.rst_n(rst_n & usrrst_n),
|
||||
.clk28(clk28),
|
||||
|
||||
.bus(bus),
|
||||
@ -239,26 +246,27 @@ reg [2:0] port_1ffd;
|
||||
reg port_dffd_d3;
|
||||
reg port_dffd_d4;
|
||||
ports ports0 (
|
||||
.rst_n(rst_n),
|
||||
.rst_n(rst_n & usrrst_n),
|
||||
.clk28(clk28),
|
||||
|
||||
.bus(bus),
|
||||
.d_out(ports_dout),
|
||||
.d_out_active(ports_dout_active),
|
||||
|
||||
.en_128k(1),
|
||||
.en_128k(1'b1),
|
||||
.en_plus3(!extlock),
|
||||
.en_profi(!extlock),
|
||||
.en_kempston(!joy_sinclair),
|
||||
.en_sinclair(joy_sinclair),
|
||||
|
||||
.clkcpu_ck(clkcpu_ck),
|
||||
.timings(timings),
|
||||
.screen_load(screen_load),
|
||||
.attr_next(attr_next),
|
||||
.kd(ps2_kd),
|
||||
.kempston_data(8'b11111111),
|
||||
.joy_sinclair(joy_sinclair),
|
||||
.kempston_data({3'b000, joy_fire, joy_up, joy_down, joy_left, joy_right}),
|
||||
.magic_active_next(magic_active_next),
|
||||
.sd_miso_tape_in(sd_miso_tape_in),
|
||||
.tape_in(sd_miso_tape_in),
|
||||
|
||||
.tape_out(tape_out),
|
||||
.beeper(beeper),
|
||||
@ -336,7 +344,7 @@ YM2149 ym2149_1(
|
||||
/* COVOX & SOUNDRIVE */
|
||||
reg [7:0] soundrive_l0, soundrive_l1, soundrive_r0, soundrive_r1;
|
||||
soundrive soundrive0(
|
||||
.rst_n(rst_n),
|
||||
.rst_n(rst_n & usrrst_n),
|
||||
.clk28(clk28),
|
||||
.en_covox(!extlock),
|
||||
.en_soundrive(!extlock),
|
||||
@ -380,7 +388,7 @@ wire [7:0] div_dout;
|
||||
reg [3:0] div_page;
|
||||
reg sd_mosi0;
|
||||
divmmc divmmc0(
|
||||
.rst_n(rst_n),
|
||||
.rst_n(rst_n & usrrst_n),
|
||||
.clk28(clk28),
|
||||
.ck14(ck14),
|
||||
.ck7(ck7),
|
||||
|
Reference in New Issue
Block a user