Support dual-way (OSD/HotKey) settings (CPU speed for now).

This commit is contained in:
sorgelig
2018-09-09 11:59:45 +08:00
parent 8c7740dc83
commit 0490b2fa2c
2 changed files with 116 additions and 79 deletions

View File

@@ -47,7 +47,9 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0)
output forced_scandoubler,
output reg [31:0] status,
input [31:0] status_in,
input status_set,
//toggle to force notify of video mode change
input new_vmode,
@@ -61,7 +63,7 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0)
input [VD:0] sd_rd, // only single sd_rd can be active at any given time
input [VD:0] sd_wr, // only single sd_wr can be active at any given time
output reg sd_ack,
// do not use in new projects.
// CID and CSD are fake except CSD image size field.
input sd_conf,
@@ -88,6 +90,9 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0)
// Seconds since 1970-01-01 00:00:00
output reg [32:0] TIMESTAMP,
// UART flags
input [15:0] uart_mode,
// ps2 keyboard emulation
output ps2_kbd_clk_out,
output ps2_kbd_data_out,
@@ -106,7 +111,7 @@ module hps_io #(parameter STRLEN=0, PS2DIV=2000, WIDE=0, VDNUM=1, PS2WE=0)
// [8] - extended, [9] - pressed, [10] - toggles with every press/release
output reg [10:0] ps2_key = 0,
// [24] - toggles with every event
output reg [24:0] ps2_mouse = 0
);
@@ -135,7 +140,7 @@ assign forced_scandoubler = cfg[4];
//cfg[5] - ypbpr handled in sys_top
// command byte read by the io controller
wire [15:0] sd_cmd =
wire [15:0] sd_cmd =
{
2'b00,
(VDNUM>=4) ? sd_wr[3] : 1'b0,
@@ -145,7 +150,7 @@ wire [15:0] sd_cmd =
(VDNUM>=4) ? sd_rd[3] : 1'b0,
(VDNUM>=3) ? sd_rd[2] : 1'b0,
(VDNUM>=2) ? sd_rd[1] : 1'b0,
4'h5, sd_conf, 1'b1,
sd_wr[0],
sd_rd[0]
@@ -261,13 +266,20 @@ always@(posedge clk_sys) begin
reg [2:0] b_wr;
reg [2:0] stick_idx;
reg ps2skip = 0;
reg [3:0] stflg = 0;
reg [31:0] status_req;
if(status_set) begin
stflg <= stflg + 1'd1;
status_req <= status_in;
end
sd_buff_wr <= b_wr[0];
if(b_wr[2] && (~&sd_buff_addr)) sd_buff_addr <= sd_buff_addr + 1'b1;
b_wr <= (b_wr<<1);
{kbd_rd,kbd_we,mouse_rd,mouse_we} <= 0;
if(~io_enable) begin
if(cmd == 4 && !ps2skip) ps2_mouse[24] <= ~ps2_mouse[24];
if(cmd == 5 && !ps2skip) begin
@@ -297,6 +309,7 @@ always@(posedge clk_sys) begin
'h19: sd_ack_conf <= 1;
'h17,
'h18: sd_ack <= 1;
'h29: io_dout <= {4'hA, stflg};
endcase
sd_buff_addr <= 0;
@@ -306,11 +319,11 @@ always@(posedge clk_sys) begin
case(cmd)
// buttons and switches
'h01: cfg <= io_din[7:0];
'h01: cfg <= io_din[7:0];
'h02: joystick_0 <= io_din;
'h03: joystick_1 <= io_din;
// store incoming ps2 mouse bytes
// store incoming ps2 mouse bytes
'h04: begin
mouse_data <= io_din[7:0];
mouse_we <= 1;
@@ -324,7 +337,7 @@ always@(posedge clk_sys) begin
end
end
// store incoming ps2 keyboard bytes
// store incoming ps2 keyboard bytes
'h05: begin
if(&io_din[15:8]) ps2skip <= 1;
if(~&io_din[15:8] & ~ps2skip) ps2_key_raw[31:0] <= {ps2_key_raw[23:0], io_din[7:0]};
@@ -332,20 +345,15 @@ always@(posedge clk_sys) begin
kbd_we <= 1;
end
// reading config string
'h14: begin
// returning a byte from string
if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8];
end
// reading config string, returning a byte from string
'h14: if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8];
// reading sd card status
'h16: begin
case(byte_cnt)
'h16: case(byte_cnt)
1: io_dout <= sd_cmd;
2: io_dout <= sd_lba[15:0];
3: io_dout <= sd_lba[31:16];
endcase
end
// send SD config IO -> FPGA
// flag that download begins
@@ -366,14 +374,11 @@ always@(posedge clk_sys) begin
end
// joystick analog
'h1a: begin
// first byte is joystick index
if(byte_cnt == 1) stick_idx <= io_din[2:0];
if(byte_cnt == 2) begin
if(stick_idx == 0) joystick_analog_0 <= io_din;
if(stick_idx == 1) joystick_analog_1 <= io_din;
end
end
'h1a: case(byte_cnt)
1: stick_idx <= io_din[2:0]; // first byte is joystick index
2: if(stick_idx == 0) joystick_analog_0 <= io_din;
else if(stick_idx == 1) joystick_analog_1 <= io_din;
endcase
// notify image selection
'h1c: begin
@@ -392,41 +397,46 @@ always@(posedge clk_sys) begin
'h1f: io_dout <= {|PS2WE, 2'b01, ps2_kbd_led_status[2], ps2_kbd_led_use[2], ps2_kbd_led_status[1], ps2_kbd_led_use[1], ps2_kbd_led_status[0], ps2_kbd_led_use[0]};
// reading ps2 keyboard/mouse control
'h21: begin
if(byte_cnt == 1) begin
'h21: if(byte_cnt == 1) begin
io_dout <= kbd_data_host;
kbd_rd <= 1;
end
else
if(byte_cnt == 2) begin
io_dout <= mouse_data_host;
mouse_rd <= 1;
end
end
//RTC
'h22: RTC[(byte_cnt-6'd1)<<4 +:16] <= io_din;
//Video res.
'h23: begin
case(byte_cnt)
1: io_dout <= vid_nres;
2: io_dout <= vid_hcnt[15:0];
3: io_dout <= vid_hcnt[31:16];
4: io_dout <= vid_vcnt[15:0];
5: io_dout <= vid_vcnt[31:16];
6: io_dout <= vid_htime[15:0];
7: io_dout <= vid_htime[31:16];
8: io_dout <= vid_vtime[15:0];
9: io_dout <= vid_vtime[31:16];
10: io_dout <= vid_pix[15:0];
11: io_dout <= vid_pix[31:16];
12: io_dout <= vid_vtime_hdmi[15:0];
13: io_dout <= vid_vtime_hdmi[31:16];
endcase
end
'h23: case(byte_cnt)
1: io_dout <= vid_nres;
2: io_dout <= vid_hcnt[15:0];
3: io_dout <= vid_hcnt[31:16];
4: io_dout <= vid_vcnt[15:0];
5: io_dout <= vid_vcnt[31:16];
6: io_dout <= vid_htime[15:0];
7: io_dout <= vid_htime[31:16];
8: io_dout <= vid_vtime[15:0];
9: io_dout <= vid_vtime[31:16];
10: io_dout <= vid_pix[15:0];
11: io_dout <= vid_pix[31:16];
12: io_dout <= vid_vtime_hdmi[15:0];
13: io_dout <= vid_vtime_hdmi[31:16];
endcase
//RTC
'h24: TIMESTAMP[(byte_cnt-6'd1)<<4 +:16] <= io_din;
//UART flags
'h28: io_dout <= uart_mode;
//status set
'h29: case(byte_cnt)
1: io_dout <= status_req[15:0];
2: io_dout <= status_req[31:16];
endcase
endcase
end
end
@@ -460,7 +470,7 @@ ps2_device keyboard
.ps2_clk(clk_ps2),
.ps2_clk_out(ps2_kbd_clk_out),
.ps2_dat_out(ps2_kbd_data_out),
.ps2_clk_in(ps2_kbd_clk_in || !PS2WE),
.ps2_dat_in(ps2_kbd_data_in || !PS2WE),
@@ -538,7 +548,7 @@ always@(posedge clk_sys) begin
begin
if(io_din[7:0]) begin
addr <= 0;
ioctl_download <= 1;
ioctl_download <= 1;
end else begin
ioctl_addr <= addr;
ioctl_download <= 0;
@@ -577,7 +587,7 @@ module ps2_device #(parameter PS2_FIFO_BITS=5)
input ps2_clk_in,
input ps2_dat_in,
output [8:0] rdata,
input rd
);
@@ -632,7 +642,7 @@ always@(posedge clk_sys) begin
rx_state <= rx_state + 1'b1;
rx_cnt <= 0;
end
2: begin
if(rx_cnt <= 7) data <= {d1, data[7:1]};
else rx_state <= rx_state + 1'b1;
@@ -643,7 +653,7 @@ always@(posedge clk_sys) begin
rx_state <= rx_state + 1'b1;
ps2_dat_out <= 0;
end
4: begin
ps2_dat_out <= 1;
has_data <= 1;
@@ -678,7 +688,7 @@ always@(posedge clk_sys) begin
if((tx_state >= 1)&&(tx_state < 9)) begin
ps2_dat_out <= tx_byte[0]; // data bits
tx_byte[6:0] <= tx_byte[7:1]; // shift down
if(tx_byte[0])
if(tx_byte[0])
parity <= !parity;
end

View File

@@ -128,6 +128,7 @@ localparam CONF_STR1 = {
"O23,Stereo mix,none,25%,50%,100%;",
"-;",
"OHJ,Joystick,Kempston,Sinclair I,Sinclair II,Sinclair I+II,Cursor;",
"OMO,CPU Speed,Original,7MHz,14MHz,28MHz,56MHz;",
"OD,Port #FF,Timex,SAA1099;",
"OE,ULA+,Enabled,Disabled;",
"OAC,Memory,Spectrum 128K/+2,Pentagon 1024K,Profi 1024K,Spectrum 48K,Spectrum +2A/+3;"
@@ -194,24 +195,38 @@ always @(negedge clk_sys) begin
ce_cpu_tn <= !((counter & turbo) ^ turbo ^ turbo[4:1]);
end
reg [4:0] turbo = 5'b11111, turbo_key = 5'b11111;
wire [4:0] turbo_req;
always_comb begin
casex({tape_active & ~status[6], status[24:22]})
'b1XXX: turbo_req = 5'b00001;
'b0001: turbo_req = 5'b01111;
'b0010: turbo_req = 5'b00111;
'b0011: turbo_req = 5'b00011;
'b0100: turbo_req = 5'b00001;
default: turbo_req = 5'b11111;
endcase
end
reg [2:0] speed_req;
always @(posedge clk_sys) begin
reg [9:4] old_Fn;
old_Fn <= Fn[9:4];
if(reset) pause <= 0;
status_set <= 0;
if(!mod) begin
if(~old_Fn[4] & Fn[4]) turbo_key <= 5'b11111;
if(~old_Fn[5] & Fn[5]) turbo_key <= 5'b01111;
if(~old_Fn[6] & Fn[6]) turbo_key <= 5'b00111;
if(~old_Fn[7] & Fn[7]) turbo_key <= 5'b00011;
if(~old_Fn[8] & Fn[8]) turbo_key <= 5'b00001;
if(~old_Fn[4] & Fn[4]) {status_set,speed_req} <= 4'b1_000;
if(~old_Fn[5] & Fn[5]) {status_set,speed_req} <= 4'b1_001;
if(~old_Fn[6] & Fn[6]) {status_set,speed_req} <= 4'b1_010;
if(~old_Fn[7] & Fn[7]) {status_set,speed_req} <= 4'b1_011;
if(~old_Fn[8] & Fn[8]) {status_set,speed_req} <= 4'b1_100;
if(~old_Fn[9] & Fn[9]) pause <= ~pause;
end
end
wire [4:0] turbo_req = (tape_active & ~status[6]) ? 5'b00001 : turbo_key;
reg [4:0] turbo = 5'b11111;
always @(posedge clk_sys) begin
reg [1:0] timeout;
@@ -272,33 +287,45 @@ wire [7:0] ioctl_dout;
wire ioctl_download;
wire [7:0] ioctl_index;
reg status_set;
reg [31:0] status_out;
hps_io #(.STRLEN(($size(CONF_STR1)>>3)+($size(CONF_STR2)>>3)+5+1)) hps_io
(
.*,
.clk_sys(clk_sys),
.HPS_BUS(HPS_BUS),
.conf_str({CONF_STR1, need_apply ? "R" : "+", CONF_STR2, plus3_fdd_ready ? CONF_PLUS3 : plusd_en ? CONF_PLUSD : CONF_BDI}),
.sd_conf(0),
.ioctl_wait(0),
.sd_ack_conf(),
.ps2_key(ps2_key),
.ps2_kbd_led_use(0),
.ps2_kbd_led_status(0),
.ps2_mouse(ps2_mouse),
// unused
.ioctl_file_ext(),
.joystick_analog_0(),
.joystick_analog_1(),
.RTC(),
.TIMESTAMP(),
.ps2_kbd_clk_out(),
.ps2_kbd_data_out(),
.ps2_mouse_clk_out(),
.ps2_mouse_data_out(),
.ps2_kbd_clk_in(1),
.ps2_kbd_data_in(1),
.ps2_mouse_clk_in(1),
.ps2_mouse_data_in(1)
.joystick_0(joystick_0),
.joystick_1(joystick_1),
.buttons(buttons),
.forced_scandoubler(forced_scandoubler),
.status(status),
.status_set(status_set),
.status_in({status[31:25],speed_req,status[21:0]}),
.sd_lba(sd_lba),
.sd_rd(sd_rd),
.sd_wr(sd_wr),
.sd_ack(sd_ack),
.sd_buff_addr(sd_buff_addr),
.sd_buff_dout(sd_buff_dout),
.sd_buff_din(sd_buff_din),
.sd_buff_wr(sd_buff_wr),
.img_mounted(img_mounted),
.img_size(img_size),
.img_readonly(img_readonly),
.ioctl_wr(ioctl_wr),
.ioctl_addr(ioctl_addr),
.ioctl_dout(ioctl_dout),
.ioctl_download(ioctl_download),
.ioctl_index(ioctl_index),
.ioctl_wait(0)
);
reg [2:0] cur_mode = 0;