From 7123b3fb5038f791a5352f937d43bf6200cdba66 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Tue, 29 Jan 2019 00:20:13 +0100 Subject: [PATCH 1/4] [C64] CIA: fix serial port Passes VICE tests --- cores/c64/rtl/mos6526.v | 85 +++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/cores/c64/rtl/mos6526.v b/cores/c64/rtl/mos6526.v index 2bacc00..01ede2b 100644 --- a/cores/c64/rtl/mos6526.v +++ b/cores/c64/rtl/mos6526.v @@ -409,40 +409,48 @@ always @(posedge clk) begin sp_shiftreg <= 8'h00; icr[3] <= 1'b0; end - else if (!cs_n && !rw) - case (rs) - 4'hc: sdr <= db_in; - default: sdr <= sdr; - endcase - if (!cra[6]) begin - if (sp_received) begin - sdr <= sp_shiftreg; - icr[3] <= 1'b1; - sp_received <= 1'b0; - sp_shiftreg <= 8'h00; - end - else if (cnt_in && !cnt_in_prev) begin - sp_shiftreg <= {sp_shiftreg[6:0], sp_in}; - sp_received <= (cnt_pulsecnt == 3'h7) ? 1'b1 : sp_received; - end - end - else if (cra[6] && !cra[3] && cra[0]) begin - if (!cs_n && !rw && rs == 8'hc) sp_pending <= 1'b1; - if (sp_pending && !sp_transmit) begin - sp_pending <= 1'b0; - sp_transmit <= 1'b1; - sp_shiftreg <= sdr; - end - else if (!cnt_out && cnt_out_prev) begin - if (cnt_pulsecnt == 3'h7) begin - icr[3] <= 1'b1; - sp_transmit <= 1'b0; + else begin + if (!cs_n && !rw) + case (rs) + 4'hc: + begin + sdr <= db_in; + sp_pending <= 1; + end + endcase + + if (phi2) begin + if (int_reset) icr[3] <= 1'b0; + + if (!cra[6]) begin // input + if (sp_received) begin + sdr <= sp_shiftreg; + icr[3] <= 1'b1; + sp_received <= 1'b0; + sp_shiftreg <= 8'h00; + end + else if (cnt_in && !cnt_in_prev) begin + sp_shiftreg <= {sp_shiftreg[6:0], sp_in}; + sp_received <= (cnt_pulsecnt == 3'h7) ? 1'b1 : sp_received; + end + end + else if (cra[6]) begin // output + if (sp_pending && !sp_transmit) begin + sp_pending <= 1'b0; + sp_transmit <= 1'b1; + sp_shiftreg <= sdr; + end + else if (!cnt_out && cnt_out_prev) begin + if (cnt_pulsecnt == 3'h7) begin + icr[3] <= 1'b1; + sp_transmit <= 1'b0; + end + sp_out <= sp_shiftreg[7]; + sp_shiftreg <= {sp_shiftreg[6:0], 1'b0}; + end end - sp_out <= sp_shiftreg[7]; - sp_shiftreg <= {sp_shiftreg[6:0], 1'b0}; end end - if (int_reset) icr[3] <= 1'b0; end // CNT Input/Output @@ -455,14 +463,15 @@ always @(posedge clk) begin else if (phi2) begin cnt_in_prev <= cnt_in; cnt_out_prev <= cnt_out; - end - if (!cra[6] && cnt_in && !cnt_in_prev) cnt_pulsecnt <= cnt_pulsecnt + 1'b1; - else if (cra[6] && !cra[3] && cra[0]) begin - if (sp_transmit) begin - cnt_out <= timerAoverflow ? ~cnt_out : cnt_out; - if (!cnt_out && cnt_out_prev) cnt_pulsecnt <= cnt_pulsecnt + 1'b1; + + if (!cra[6] && cnt_in && !cnt_in_prev) cnt_pulsecnt <= cnt_pulsecnt + 1'b1; + else if (cra[6]) begin + if (sp_transmit) begin + cnt_out <= timerAoverflow ? ~cnt_out : cnt_out; + if (!cnt_out && cnt_out_prev) cnt_pulsecnt <= cnt_pulsecnt + 1'b1; + end + else cnt_out <= timerAoverflow ? 1'b1 : cnt_out; end - else cnt_out <= timerAoverflow ? 1'b1 : cnt_out; end end From c54bc6e582e9835c19c605153f63b73eb524da40 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Tue, 29 Jan 2019 10:19:14 +0100 Subject: [PATCH 2/4] [C64] CIA: selectable old and new CIA versions --- cores/c64/rtl/fpga64_sid_iec.vhd | 7 ++++++- cores/c64/rtl/mist/c64_mist.vhd | 2 ++ cores/c64/rtl/mos6526.v | 5 +++-- cores/c64/rtl/mos6526.vhd | 1 + 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cores/c64/rtl/fpga64_sid_iec.vhd b/cores/c64/rtl/fpga64_sid_iec.vhd index 7a9fa96..38c169c 100644 --- a/cores/c64/rtl/fpga64_sid_iec.vhd +++ b/cores/c64/rtl/fpga64_sid_iec.vhd @@ -108,7 +108,10 @@ entity fpga64_sid_iec is iec_clk_i : in std_logic; iec_atn_o : out std_logic; -- iec_atn_i : in std_logic; - + + -- CIA + cia_mode : in std_logic; + disk_num : out std_logic_vector(7 downto 0); c64rom_addr : in std_logic_vector(13 downto 0); @@ -619,6 +622,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID) -- ----------------------------------------------------------------------- cia1: mos6526 port map ( + mode => cia_mode, clk => clk32, phi2 => enableCia, res_n => not reset, @@ -645,6 +649,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID) cia2: mos6526 port map ( + mode => cia_mode, clk => clk32, phi2 => enableCia, res_n => not reset, diff --git a/cores/c64/rtl/mist/c64_mist.vhd b/cores/c64/rtl/mist/c64_mist.vhd index bf78c3a..7dbdb53 100644 --- a/cores/c64/rtl/mist/c64_mist.vhd +++ b/cores/c64/rtl/mist/c64_mist.vhd @@ -134,6 +134,7 @@ constant CONF_STR : string := "OD,SID,6581,8580;"& "O3,Joysticks,normal,swapped;"& "O6,Audio filter,On,Off;"& + "O4,CIA Model,6256,8521;"& -- "OB,BIOS,C64,C64GS;" & "T5,Reset & Detach Cartridge;"; @@ -842,6 +843,7 @@ begin iec_data_i => c64_iec_data_i, iec_clk_i => c64_iec_clk_i, -- iec_atn_i => not c64_iec_atn_i, + cia_mode => status(4), disk_num => open, c64rom_addr => ioctl_addr(13 downto 0), c64rom_data => ioctl_data, diff --git a/cores/c64/rtl/mos6526.v b/cores/c64/rtl/mos6526.v index 01ede2b..d4cd9ca 100644 --- a/cores/c64/rtl/mos6526.v +++ b/cores/c64/rtl/mos6526.v @@ -5,6 +5,7 @@ // TODO: check if Flag and Serial port interrupts are still working module mos6526 ( + input wire mode, // 0 - 6526 "old", 1 - 8521 "new" input wire clk, input wire phi2, input wire res_n, @@ -492,11 +493,11 @@ always @(posedge clk) begin int_reset <= 0; if (!cs_n && rw && rs == 4'hd) int_reset <= 1; - if (phi2) begin + if (phi2 | mode) begin imr <= imr_reg[7] ? imr | imr_reg[4:0] : imr & ~imr_reg[4:0]; irq_n <= irq_n ? ~|(imr & icr) : irq_n; - if (int_reset) irq_n <= 1; end + if (phi2 & int_reset) irq_n <= 1; end end diff --git a/cores/c64/rtl/mos6526.vhd b/cores/c64/rtl/mos6526.vhd index af92849..1585df6 100644 --- a/cores/c64/rtl/mos6526.vhd +++ b/cores/c64/rtl/mos6526.vhd @@ -4,6 +4,7 @@ use IEEE.std_logic_1164.all; package mos6526 is component mos6526 PORT ( + mode : in std_logic; -- '0' - 6256, '1' - 8521 clk : in std_logic; phi2 : in std_logic; res_n : in std_logic; From 142cba49bbae41947f41665bb05bbd5d90bdaa30 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Thu, 31 Jan 2019 18:53:07 +0100 Subject: [PATCH 3/4] [C64] Use the RDY line of the CPU ...to not miss NMI edges. Fixes Turbo Outrun samples. --- cores/c64/rtl/cpu_6510.vhd | 3 ++- cores/c64/rtl/fpga64_sid_iec.vhd | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cores/c64/rtl/cpu_6510.vhd b/cores/c64/rtl/cpu_6510.vhd index 135b06d..cbe719f 100644 --- a/cores/c64/rtl/cpu_6510.vhd +++ b/cores/c64/rtl/cpu_6510.vhd @@ -28,6 +28,7 @@ entity cpu_6510 is nmi_n : in std_logic; nmi_ack : out std_logic; irq_n : in std_logic; + rdy : in std_logic; di : in unsigned(7 downto 0); do : out unsigned(7 downto 0); @@ -60,7 +61,7 @@ begin Res_n => not reset, Enable => enable, Clk => clk, - Rdy => '1', + Rdy => rdy, Abort_n => '1', IRQ_n => irq_n, NMI_n => nmi_n, diff --git a/cores/c64/rtl/fpga64_sid_iec.vhd b/cores/c64/rtl/fpga64_sid_iec.vhd index 38c169c..e06f151 100644 --- a/cores/c64/rtl/fpga64_sid_iec.vhd +++ b/cores/c64/rtl/fpga64_sid_iec.vhd @@ -372,10 +372,7 @@ begin enableVic <= '1'; when CYCLE_CPUE => enableVic <= '1'; - if baLoc = '1' - or cpuWe = '1' then - enableCpu <= '1'; - end if; + enableCpu <= '1'; when CYCLE_CPUF => enableCia <= '1'; when others => @@ -616,7 +613,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID) audio_data => audio_8580, extfilter_en => extfilter_en ); - + -- ----------------------------------------------------------------------- -- CIAs -- ----------------------------------------------------------------------- @@ -686,6 +683,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID) nmi_n => nmiLoc, nmi_ack => nmi_ack, irq_n => irqLoc, + rdy => baLoc, di => cpuDi, addr => cpuAddr, From 0f1eb4330100306347961d4d98227a8146e88c71 Mon Sep 17 00:00:00 2001 From: Gyorgy Szombathelyi Date: Thu, 31 Jan 2019 18:54:17 +0100 Subject: [PATCH 4/4] [C64] SID: read back the last written value --- cores/c64/rtl/sid/sid_regs.vhd | 16 +++------------- cores/c64/rtl/sid8580/sid8580.sv | 4 +++- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/cores/c64/rtl/sid/sid_regs.vhd b/cores/c64/rtl/sid/sid_regs.vhd index 1ff1ca5..c145cb8 100644 --- a/cores/c64/rtl/sid/sid_regs.vhd +++ b/cores/c64/rtl/sid/sid_regs.vhd @@ -98,6 +98,7 @@ architecture gideon of sid_regs is signal sust_rel : byte_array_t(0 to 15) := (others => (others => '0')); signal do_write : std_logic; signal wdata_d : std_logic_vector(7 downto 0); + signal last_write : std_logic_vector(7 downto 0); signal filt_en_i: std_logic_vector(15 downto 0) := (others => '0'); constant address_remap : byte_array_t(0 to 255) := ( @@ -159,6 +160,7 @@ begin wdata_d <= wdata; if do_write='0' and wren='1' then + last_write <= wdata_d; if address(3)='0' then -- Voice register case address(2 downto 0) is when "000" => freq_lo(to_integer(address(7 downto 4))) <= wdata_d; @@ -209,20 +211,8 @@ begin when "00011010" => rdata <= poty; when "00011011" => rdata <= osc3; when "00011100" => rdata <= env3; - when others => rdata <= (others => '0'); + when others => rdata <= last_write; end case; - if address(3) = '0' then - case address(2 downto 0) is - when "000" => rdata <= freq_lo(to_integer(address(7 downto 4))); - when "001" => rdata <= freq_hi(to_integer(address(7 downto 4))); - when "010" => rdata <= phase_lo(to_integer(address(7 downto 4))); - when "011" => rdata <= "0000" & phase_hi(to_integer(address(7 downto 4))); - when "100" => rdata <= control(to_integer(address(7 downto 4))); - when "101" => rdata <= att_dec(to_integer(address(7 downto 4))); - when "110" => rdata <= sust_rel(to_integer(address(7 downto 4))); - when others => null; - end case; - end if; if reset='1' then freq_lo <= (others => (others => '0')); diff --git a/cores/c64/rtl/sid8580/sid8580.sv b/cores/c64/rtl/sid8580/sid8580.sv index 8f27acf..6d3e3e3 100644 --- a/cores/c64/rtl/sid8580/sid8580.sv +++ b/cores/c64/rtl/sid8580/sid8580.sv @@ -150,13 +150,14 @@ assign data_out = do_buf; //assign unsigned_audio = unsigned_filt[18:1]; //assign audio_data = filtered_audio[18:3];// + 15'h4000;//{1'b0, unsigned_audio[17:1]}; +reg [7:0] last_wr; always @(*) begin case (addr) 5'h19: do_buf = pot_x; 5'h1a: do_buf = pot_y; 5'h1b: do_buf = Misc_Osc3_Random; 5'h1c: do_buf = Misc_Env3; - default: do_buf = 0; + default: do_buf = last_wr; endcase end @@ -192,6 +193,7 @@ always @(posedge clk) begin end else begin if (we) begin + last_wr <= data_in; case (addr) 5'h00: Voice_1_Freq_lo <= data_in; 5'h01: Voice_1_Freq_hi <= data_in;