diff --git a/cores/c64/rtl/fpga64_sid_iec.vhd b/cores/c64/rtl/fpga64_sid_iec.vhd index f81f3b9..61a1edf 100644 --- a/cores/c64/rtl/fpga64_sid_iec.vhd +++ b/cores/c64/rtl/fpga64_sid_iec.vhd @@ -86,6 +86,10 @@ entity fpga64_sid_iec is -- joystick interface joyA : in unsigned(6 downto 0); joyB : in unsigned(6 downto 0); + potA_x : in std_logic_vector(7 downto 0); + potA_y : in std_logic_vector(7 downto 0); + potB_x : in std_logic_vector(7 downto 0); + potB_y : in std_logic_vector(7 downto 0); -- serial port, for connection to pheripherals serioclk : out std_logic; @@ -600,8 +604,14 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID) sid_do8580_l when second_sid_en='0' else sid_do8580_r; - pot_x <= X"FF" when ((cia1_pao(7) and JoyA(5)) or (cia1_pao(6) and JoyB(5))) = '0' else X"00"; - pot_y <= X"FF" when ((cia1_pao(7) and JoyA(6)) or (cia1_pao(6) and JoyB(6))) = '0' else X"00"; + -- CD4066 analogue switch + pot_x <= potA_x when cia1_pao(6) = '1' else + potB_x when cia1_pao(7) = '1' else + x"FF"; + pot_y <= potA_y when cia1_pao(6) = '1' else + potB_y when cia1_pao(7) = '1' else + x"FF"; + second_sid_en <= '0' when sid_mode(0) = '0' else '1' when cpuAddr(11 downto 8) = x"4" and cpuAddr(5) = '1' else -- D420 '1' when cpuAddr(11 downto 8) = x"5" else -- D500 diff --git a/cores/c64/rtl/mist/c64_mist.vhd b/cores/c64/rtl/mist/c64_mist.vhd index 55dfbac..b2fff5d 100644 --- a/cores/c64/rtl/mist/c64_mist.vhd +++ b/cores/c64/rtl/mist/c64_mist.vhd @@ -199,7 +199,11 @@ component user_io generic(STRLEN : integer := 0 ); port ps2_kbd_data : out std_logic; ps2_mouse_clk : out std_logic; - ps2_mouse_data : out std_logic + ps2_mouse_data : out std_logic; + mouse_x : out signed(8 downto 0); + mouse_y : out signed(8 downto 0); + mouse_flags : out std_logic_vector(8 downto 0); -- YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn + mouse_strobe : out std_logic ); end component user_io; @@ -388,6 +392,10 @@ end component cartridge; signal joyB_c64 : std_logic_vector(6 downto 0); signal joyC_c64 : std_logic_vector(6 downto 0); signal joyD_c64 : std_logic_vector(6 downto 0); + signal potA_x : std_logic_vector(7 downto 0); + signal potA_y : std_logic_vector(7 downto 0); + signal potB_x : std_logic_vector(7 downto 0); + signal potB_y : std_logic_vector(7 downto 0); signal reset_key : std_logic; signal cart_detach_key :std_logic; -- cartridge detach key CTRL-D - LCA @@ -418,7 +426,15 @@ end component cartridge; signal ps2_clk : std_logic; signal ps2_dat : std_logic; - + signal mouse_en : std_logic; + signal mouse_x : signed( 8 downto 0); + signal mouse_x_pos : signed(10 downto 0); + signal mouse_y : signed( 8 downto 0); + signal mouse_y_pos : signed(10 downto 0); + signal mouse_flags : std_logic_vector(8 downto 0); + signal mouse_btns : std_logic_vector(1 downto 0); + signal mouse_strobe : std_logic; + signal c64_iec_atn_i : std_logic; signal c64_iec_clk_o : std_logic; signal c64_iec_data_o : std_logic; @@ -538,7 +554,11 @@ begin sd_dout_strobe => sd_buff_wr, img_mounted => sd_change, ps2_kbd_clk => ps2_clk, - ps2_kbd_data => ps2_dat + ps2_kbd_data => ps2_dat, + mouse_x => mouse_x, + mouse_y => mouse_y, + mouse_flags => mouse_flags, + mouse_strobe => mouse_strobe ); data_io_d: data_io @@ -603,8 +623,8 @@ begin ); -- rearrange joystick contacta for c64 - joyA_int <= joyA(6 downto 4) & joyA(0) & joyA(1) & joyA(2) & joyA(3); - joyB_int <= joyB(6 downto 4) & joyB(0) & joyB(1) & joyB(2) & joyB(3); + joyA_int <= joyA(6 downto 5) & (joyA(4) or (mouse_en and mouse_btns(0))) & joyA(0) & joyA(1) & joyA(2) & (joyA(3) or (mouse_en and mouse_btns(1))); + joyB_int <= joyB(6 downto 5) & (joyB(4) or (mouse_en and mouse_btns(0))) & joyB(0) & joyB(1) & joyB(2) & (joyB(3) or (mouse_en and mouse_btns(1))); joyC_c64 <= joyC(6 downto 4) & joyC(0) & joyC(1) & joyC(2) & joyC(3); joyD_c64 <= joyD(6 downto 4) & joyD(0) & joyD(1) & joyD(2) & joyD(3); @@ -962,6 +982,10 @@ begin ba => open, joyA => unsigned(joyA_c64), joyB => unsigned(joyB_c64), + potA_x => potA_x, + potA_y => potA_y, + potB_x => potB_x, + potB_y => potB_y, serioclk => open, ces => ces, SIDclk => open, @@ -992,6 +1016,39 @@ begin reset_key => reset_key ); + -- paddle pins - mouse or GS controller + potA_x <= '0' & std_logic_vector(mouse_x_pos)(6 downto 1) & '0' when mouse_en = '1' + else x"00" when joyA_c64(5) = '1' else x"FF"; + potA_y <= '0' & std_logic_vector(mouse_y_pos)(6 downto 1) & '0' when mouse_en = '1' + else x"00" when joyA_c64(6) = '1' else x"FF"; + potB_x <= '0' & std_logic_vector(mouse_x_pos)(6 downto 1) & '0' when mouse_en = '1' + else x"00" when joyB_c64(5) = '1' else x"FF"; + potB_y <= '0' & std_logic_vector(mouse_y_pos)(6 downto 1) & '0' when mouse_en = '1' + else x"00" when joyB_c64(6) = '1' else x"FF"; + + process(clk_c64, reset_n) + variable mov_x: signed(6 downto 0); + variable mov_y: signed(6 downto 0); + begin + if reset_n = '0' then + mouse_x_pos <= (others => '0'); + mouse_y_pos <= (others => '0'); + mouse_en <= '0'; + elsif rising_edge(clk_c64) then + if mouse_strobe = '1' then + mouse_en <= '1'; + -- due to limited resolution on the c64 side, limit the mouse movement speed + if mouse_x > 40 then mov_x:="0101000"; elsif mouse_x < -40 then mov_x:= "1011000"; else mov_x := mouse_x(6 downto 0); end if; + if mouse_y > 40 then mov_y:="0101000"; elsif mouse_y < -40 then mov_y:= "1011000"; else mov_y := mouse_y(6 downto 0); end if; + mouse_x_pos <= mouse_x_pos + mov_x; + mouse_y_pos <= mouse_y_pos + mov_y; + mouse_btns <= mouse_flags(1 downto 0); + elsif joya(7 downto 0) /= 0 or joyb(7 downto 0) /= 0 then + mouse_en <= '0'; + end if; + end if; + end process; + -- connect user port process (pa2_out, pb_out, joyC_c64, joyD_c64, UART_RX, status) begin diff --git a/cores/c64/rtl/mist/user_io.v b/cores/c64/rtl/mist/user_io.v index 999c474..5b03cd1 100644 --- a/cores/c64/rtl/mist/user_io.v +++ b/cores/c64/rtl/mist/user_io.v @@ -63,12 +63,18 @@ module user_io #(parameter STRLEN=0, parameter PS2DIV=100) ( output reg img_mounted, //rising edge if a new image is mounted output reg [31:0] img_size, // size of image in bytes - // ps2 keyboard emulation + // ps2 keyboard/mouse emulation output ps2_kbd_clk, output reg ps2_kbd_data, output ps2_mouse_clk, output reg ps2_mouse_data, + // mouse data + output reg [8:0] mouse_x, + output reg [8:0] mouse_y, + output reg [7:0] mouse_flags, // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn + output reg mouse_strobe, // mouse data is valid on mouse_strobe + // serial com port input [7:0] serial_data, input serial_strobe @@ -374,12 +380,17 @@ always @(posedge clk_sys) begin reg [7:0] acmd; reg [7:0] abyte_cnt; // counts bytes + reg [7:0] mouse_flags_r; + reg [7:0] mouse_x_r; + //synchronize between SPI and sys clock domains spi_receiver_strobeD <= spi_receiver_strobe_r; spi_receiver_strobe <= spi_receiver_strobeD; spi_transfer_endD <= spi_transfer_end_r; spi_transfer_end <= spi_transfer_endD; + mouse_strobe <= 0; + if (~spi_transfer_endD & spi_transfer_end) begin abyte_cnt <= 8'd0; end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin @@ -402,6 +413,15 @@ always @(posedge clk_sys) begin // store incoming ps2 mouse bytes ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in; ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1; + if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in; + else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in; + else if (abyte_cnt == 3) begin + // flags: YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn + mouse_flags <= mouse_flags_r; + mouse_x <= { mouse_flags_r[4], mouse_x_r }; + mouse_y <= { mouse_flags_r[5], spi_byte_in }; + mouse_strobe <= 1; + end end 8'h05: begin // store incoming ps2 keyboard bytes @@ -446,6 +466,7 @@ always @(posedge clk_sd) begin reg spi_transfer_end; reg spi_receiver_strobeD; reg spi_transfer_endD; + reg sd_wrD; reg [7:0] acmd; reg [7:0] abyte_cnt; // counts bytes @@ -460,9 +481,12 @@ always @(posedge clk_sd) begin if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; end - if(sd_din_strobe) begin - sd_din_strobe<= 0; - if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; + sd_din_strobe<= 0; + sd_wrD <= sd_wr; + // fetch the first byte immediately after the write command seen + if (~sd_wrD & sd_wr) begin + sd_buff_addr <= 0; + sd_din_strobe <= 1; end img_mounted <= 0; @@ -473,7 +497,7 @@ always @(posedge clk_sd) begin sd_ack_conf <= 1'b0; sd_dout_strobe <= 1'b0; sd_din_strobe <= 1'b0; - sd_buff_addr<= 0; + sd_buff_addr <= 0; end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin if(~&abyte_cnt) @@ -482,9 +506,10 @@ always @(posedge clk_sd) begin if(abyte_cnt == 0) begin acmd <= spi_byte_in; - // fetch first byte when sectore FPGA->IO command has been seen - if(spi_byte_in == 8'h18) + if(spi_byte_in == 8'h18) begin sd_din_strobe <= 1'b1; + if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; + end if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18)) sd_ack <= 1'b1; @@ -500,7 +525,10 @@ always @(posedge clk_sd) begin end // send sector FPGA -> IO - 8'h18: sd_din_strobe <= 1'b1; + 8'h18: begin + sd_din_strobe <= 1'b1; + if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1; + end // send SD config IO -> FPGA 8'h19: begin