From 0abc502d90eb88a14e8fff082df7526831634631 Mon Sep 17 00:00:00 2001 From: Antonino Porcino Date: Tue, 16 Apr 2019 18:54:10 +0200 Subject: [PATCH 1/7] refactor tape, add EAR/MIC support --- cores/c64/rtl/c1530.vhd | 131 ++++++++++++++++++++----------- cores/c64/rtl/fpga64_sid_iec.vhd | 4 +- cores/c64/rtl/mist/c64_mist.vhd | 57 ++++++-------- 3 files changed, 111 insertions(+), 81 deletions(-) diff --git a/cores/c64/rtl/c1530.vhd b/cores/c64/rtl/c1530.vhd index 11c9b11..c2b9c29 100644 --- a/cores/c64/rtl/c1530.vhd +++ b/cores/c64/rtl/c1530.vhd @@ -14,22 +14,26 @@ use ieee.numeric_std.all; entity c1530 is port( - clk32 : in std_logic; - restart_tape : in std_logic; -- keep to 1 to long enough to clear fifo - -- reset tap header bytes skip counter + clk32 : in std_logic; + restart_tape : in std_logic; -- keep to 1 to long enough to clear fifo + -- reset tap header bytes skip counter - wav_mode : in std_logic; -- 1 for wav mode, 0 for tap mode - tap_mode1 : in std_logic; -- 1 for tap version 1, 0 for tap version 0 + wav_mode : in std_logic; -- 1 for wav mode, 0 for tap mode + tap_version : in std_logic; -- tap file version (0 or 1) - host_tap_in : in std_logic_vector(7 downto 0); -- 8bits fifo input - host_tap_wrreq : in std_logic; -- set to 1 for 1 clk32 to write 1 word + host_tap_in : in std_logic_vector(7 downto 0); -- 8bits fifo input + host_tap_wrreq : in std_logic; -- set to 1 for 1 clk32 to write 1 word tap_fifo_wrfull : out std_logic; -- do not write when fifo tap_fifo_full = 1 + tap_fifo_error : out std_logic; -- fifo fall empty (unrecoverable error) - tap_fifo_error : out std_logic; -- fifo fall empty (unrecoverable error) - - play : in std_logic; -- 1 = read tape, 0 = stop reading - do : out std_logic -- tape signal out - + osd_play_stop_toggle : in std_logic; -- PLAY/STOP toggle button from OSD + + cass_sense : out std_logic; -- 0 = PLAY/REW/FF/REC button is pressed + cass_read : out std_logic; -- tape read signal + cass_write : in std_logic; -- signal to write on tape (not used) + cass_motor : in std_logic; -- 0 = tape motor is powered + + ear_input : in std_logic -- tape input from EAR port ); end c1530; @@ -37,18 +41,27 @@ architecture struct of c1530 is signal tap_player_tick_cnt : std_logic_vector( 5 downto 0); signal wav_player_tick_cnt : std_logic_vector(11 downto 0); -signal tap_dword : std_logic_vector(31 downto 0); -signal wave_cnt : std_logic_vector(23 downto 0); -signal wave_len : std_logic_vector(23 downto 0); +signal tap_dword : std_logic_vector(31 downto 0); +signal wave_cnt : std_logic_vector(23 downto 0); +signal wave_len : std_logic_vector(23 downto 0); -signal tap_fifo_do : std_logic_vector(7 downto 0); +signal tap_fifo_do : std_logic_vector(7 downto 0); signal tap_fifo_rdreq : std_logic; signal tap_fifo_empty : std_logic; signal get_24bits_len : std_logic; -signal start_bytes : std_logic_vector(7 downto 0); -signal skip_bytes : std_logic; -signal playing : std_logic; +signal start_bytes : std_logic_vector(7 downto 0); +signal skip_bytes : std_logic; +signal playing : std_logic; -- 1 = tap or wav file is playing +signal osd_play_stop_toggleD : std_logic; -- for detecting change in the OSD toggle button +signal sense : std_logic; -- status of the PLAY/STOP tape button + +signal ear_inputD : std_logic; -- for detecting input from EAR port +signal ear_input_detected : std_logic; -- 1=input from EAR port was detected +signal ear_autostop_counter : std_logic_vector(28 downto 0); -- counter for stopping after a delay when ear is no longer detected + +constant autostop_time: std_logic_vector(28 downto 0) := std_logic_vector(to_unsigned(32000000 * 5, ear_autostop_counter'length)); -- about 5 seconds + begin -- for wav mode use large depth fifo (eg 512 x 32bits) @@ -60,7 +73,7 @@ port map( clock => clk32, rdreq => tap_fifo_rdreq, wrreq => host_tap_wrreq, - q => tap_fifo_do, + q => tap_fifo_do, empty => tap_fifo_empty, full => tap_fifo_wrfull ); @@ -77,13 +90,43 @@ begin wave_len <= (others => '0'); wave_cnt <= (others => '0'); get_24bits_len <= '0'; - playing <= '0'; tap_fifo_rdreq <='0'; tap_fifo_error <='0'; -- run out of data + + sense <= '1'; -- STOP tape elsif rising_edge(clk32) then + -- detect OSD PLAY/STOP button press + osd_play_stop_toggleD <= osd_play_stop_toggle; + if osd_play_stop_toggleD = '0' and osd_play_stop_toggle = '1' then + sense <= not sense; + end if; + + -- detect EAR input + ear_inputD <= ear_input; + if ear_inputD /= ear_input then + ear_input_detected <= '1'; + ear_autostop_counter <= autostop_time; + end if; + + -- EAR input + if ear_input_detected='1' then + sense <= '0'; -- automatically press PLAY + cass_read <= not ear_input; + + -- autostop + if ear_autostop_counter = 0 then + ear_input_detected <= '0'; + sense <= '1'; -- automatically press STOP + else + ear_autostop_counter <= ear_autostop_counter - "1"; + end if; + end if; + + playing <= (not cass_motor) and (not sense) and (not ear_input_detected); -- cass_motor and sense are low active + tap_fifo_rdreq <= '0'; if playing = '0' then tap_fifo_error <= '0'; @@ -91,14 +134,13 @@ begin wave_len <= (others => '0'); tap_player_tick_cnt <= (others => '0'); wav_player_tick_cnt <= (others => '0'); - end if; - if play = '1' then playing <= '1'; end if; + end if; - if ((playing = '1') and (wav_mode = '1')) then + if (playing = '1') and (wav_mode = '1') then -- Wav player required a large depth fifo to give chance -- fifo not falling empty while host go reading next sd card sector - -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) + -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) wav_player_tick_cnt <= wav_player_tick_cnt + '1'; @@ -114,13 +156,13 @@ begin end if; end if; - do <= not tap_fifo_do(7); -- only use msb (wav data is either xFF or x00/x01) + cass_read <= not tap_fifo_do(7); -- only use msb (wav data is either xFF or x00/x01) end if; -- play wav mode -- tap player - if ((playing = '1') and (wav_mode = '0')) then + if (playing = '1') and (wav_mode = '0') then tap_player_tick_cnt <= tap_player_tick_cnt + '1'; @@ -128,10 +170,10 @@ begin if ((tap_player_tick_cnt = "011111") and (skip_bytes = '0')) then -- divide by 32 -- square wave period (1/2 duty cycle not mendatory, only falling edge matter) - if wave_cnt > '0'&wave_len(10 downto 1) then - do <= '1'; + if wave_cnt > '0' & wave_len(10 downto 1) then + cass_read <= '1'; else - do <= '0'; + cass_read <= '0'; end if; tap_player_tick_cnt <= "000000"; @@ -139,26 +181,21 @@ begin if wave_cnt >= wave_len then wave_cnt <= (others => '0'); - if play = '0' then - playing <= '0'; - do <= '0'; + if tap_fifo_empty = '1' then + tap_fifo_error <= '1'; else - if tap_fifo_empty = '1' then - tap_fifo_error <= '1'; + tap_fifo_rdreq <= '1'; + if tap_fifo_do = x"00" then + wave_len <= x"000100"; -- interpret data x00 for tap version 0 + get_24bits_len <= tap_version; else - tap_fifo_rdreq <= '1'; - if tap_fifo_do = x"00" then - wave_len <= x"000100"; -- interpret data x00 for mode 0 - get_24bits_len <= tap_mode1; - else - wave_len <= '0'&x"000" & tap_fifo_do & "000"; - end if; + wave_len <= '0'&x"000" & tap_fifo_do & "000"; end if; end if; end if; end if; -- tap_player_tick_cnt = "100000" - -- catch 24bits wave_len for data x00 in tap mode 1 + -- catch 24bits wave_len for data x00 in tap version 1 if (get_24bits_len = '1' ) and (skip_bytes = '0') and (tap_player_tick_cnt(0) = '1') then if tap_player_tick_cnt = "000101" then @@ -172,13 +209,13 @@ begin wave_len <= tap_fifo_do & wave_len(23 downto 8); end if; - do <= '1'; + cass_read <= '1'; end if; -- skip tap header bytes if (skip_bytes = '1' and tap_fifo_empty = '0') then tap_fifo_rdreq <= '1'; - do <= '1'; + cass_read <= '1'; if start_bytes < X"1A" then -- little more than x14 start_bytes <= start_bytes + X"01"; else @@ -186,9 +223,11 @@ begin end if; end if; - end if; -- play tap mode + end if; -- play tap end if; -- clk32 end process; +cass_sense <= sense; + end struct; diff --git a/cores/c64/rtl/fpga64_sid_iec.vhd b/cores/c64/rtl/fpga64_sid_iec.vhd index 6d63f90..b69d531 100644 --- a/cores/c64/rtl/fpga64_sid_iec.vhd +++ b/cores/c64/rtl/fpga64_sid_iec.vhd @@ -134,7 +134,7 @@ entity fpga64_sid_iec is cass_motor : out std_logic; cass_write : out std_logic; cass_sense : in std_logic; - cass_do : in std_logic; + cass_read : in std_logic; disk_num : out std_logic_vector(7 downto 0); @@ -702,7 +702,7 @@ div1m: process(clk32) -- this process devides 32 MHz to 1MHz (for the SID) pb_in => std_logic_vector(cia1_pbi), unsigned(pb_out) => cia1_pbo, - flag_n => cass_do, + flag_n => cass_read, sp_in => sp1_in, sp_out => sp1_out, cnt_in => cnt1_in, diff --git a/cores/c64/rtl/mist/c64_mist.vhd b/cores/c64/rtl/mist/c64_mist.vhd index 51f8fe3..03d113e 100644 --- a/cores/c64/rtl/mist/c64_mist.vhd +++ b/cores/c64/rtl/mist/c64_mist.vhd @@ -521,19 +521,16 @@ end component cartridge; signal cass_motor : std_logic; signal cass_write : std_logic; signal cass_sense : std_logic; - signal cass_do : std_logic; - signal tap_mem_ce : std_logic; + signal cass_read : std_logic; + + signal tap_mem_ce : std_logic; signal tap_play_addr : std_logic_vector(24 downto 0); - signal tap_last_addr : std_logic_vector(24 downto 0); - signal tap_in : std_logic_vector(7 downto 0); - signal tap_reset : std_logic; - signal tap_wrreq : std_logic; - signal tap_wrfull : std_logic; + signal tap_last_addr : std_logic_vector(24 downto 0); + signal tap_reset : std_logic; + signal tap_wrreq : std_logic; + signal tap_wrfull : std_logic; signal tap_fifo_error : std_logic; - signal tap_mode : std_logic; - signal tap_play : std_logic; - signal tap_play_btn: std_logic; - signal tap_play_btnD: std_logic; + signal tap_version : std_logic; signal reset_counter : integer; signal reset_n : std_logic; @@ -999,8 +996,8 @@ begin ); audio_data_l_mix <= audio_data_l when st_tape_sound = '0' else - audio_data_l + (cass_do & "00000000000000"); --- (cass_do & "00000000000000000"); + audio_data_l + ((cass_read or cass_write) & "00000000000000"); +-- (cass_read & "00000000000000000"); dac : sigma_delta_dac port map ( @@ -1078,9 +1075,9 @@ begin cass_motor => cass_motor, cass_write => cass_write, + cass_read => cass_read, cass_sense => cass_sense, - cass_do => cass_do, - + c64rom_addr => c64rom_addr, c64rom_data => ioctl_data, c64rom_wr => c64rom_wr, @@ -1225,35 +1222,25 @@ begin led => led_disk ); - -- TAP playback controller - cass_sense <= not tap_play; - tap_play_btn <= st_tap_play_btn; - + -- TAP playback controller process(clk_c64, reset_n) begin if reset_n = '0' then tap_play_addr <= TAP_MEM_START; - tap_last_addr <= TAP_MEM_START; - tap_play <= '0'; + tap_last_addr <= TAP_MEM_START; tap_reset <= '1'; tap_mem_ce <= '0'; elsif rising_edge(clk_c64) then tap_reset <= '0'; - if ioctl_download = '1' and ioctl_index = FILE_TAP then - tap_play <= '0'; + if ioctl_download = '1' and ioctl_index = FILE_TAP then tap_play_addr <= TAP_MEM_START; tap_last_addr <= ioctl_load_addr; tap_reset <= '1'; if ioctl_addr = x"00000C" and ioctl_wr = '1' then - tap_mode <= ioctl_data(0); + tap_version <= ioctl_data(0); end if; end if; - tap_play_btnD <= tap_play_btn; - if tap_play_btnD = '0' and tap_play_btn = '1' then - tap_play <= not tap_play; - end if; - -- if tap_fifo_error = '1' then tap_play <= '0'; end if; iec_cycle_rD <= iec_cycle; @@ -1276,13 +1263,17 @@ begin clk32 => clk_c64, restart_tape => tap_reset, wav_mode => '0', - tap_mode1 => tap_mode, + tap_version => tap_version, host_tap_in => c64_data_in, host_tap_wrreq => tap_wrreq, tap_fifo_wrfull => tap_wrfull, - tap_fifo_error => tap_fifo_error, - play => not cass_motor and not tap_reset, - do => cass_do + tap_fifo_error => tap_fifo_error, + cass_read => cass_read, + cass_write => cass_write, + cass_motor => cass_motor, + cass_sense => cass_sense, + osd_play_stop_toggle => st_tap_play_btn, + ear_input => UART_RX ); comp_sync : entity work.composite_sync From 83b979e28dcbdd21e9f6e60e47e855bac0ba5503 Mon Sep 17 00:00:00 2001 From: Antonino Porcino Date: Wed, 17 Apr 2019 10:02:47 +0200 Subject: [PATCH 2/7] invert polarity of tape audio signals --- cores/c64/rtl/mist/c64_mist.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/c64/rtl/mist/c64_mist.vhd b/cores/c64/rtl/mist/c64_mist.vhd index 03d113e..e77c2a1 100644 --- a/cores/c64/rtl/mist/c64_mist.vhd +++ b/cores/c64/rtl/mist/c64_mist.vhd @@ -996,7 +996,7 @@ begin ); audio_data_l_mix <= audio_data_l when st_tape_sound = '0' else - audio_data_l + ((cass_read or cass_write) & "00000000000000"); + audio_data_l + ((not (cass_read or cass_write)) & "00000000000000"); -- (cass_read & "00000000000000000"); dac : sigma_delta_dac From 255dac8ccccdfe69f23045fe519876b047a628cc Mon Sep 17 00:00:00 2001 From: Antonino Porcino Date: Wed, 17 Apr 2019 11:27:35 +0200 Subject: [PATCH 3/7] remove bad character --- cores/c64/rtl/c1530.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/c64/rtl/c1530.vhd b/cores/c64/rtl/c1530.vhd index c2b9c29..7146113 100644 --- a/cores/c64/rtl/c1530.vhd +++ b/cores/c64/rtl/c1530.vhd @@ -140,7 +140,7 @@ begin -- Wav player required a large depth fifo to give chance -- fifo not falling empty while host go reading next sd card sector - -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) + -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) wav_player_tick_cnt <= wav_player_tick_cnt + '1'; From ab6417c6faa211a2f78b3aa3b3dee2fb99feead8 Mon Sep 17 00:00:00 2001 From: nino-porcino Date: Wed, 17 Apr 2019 16:42:11 +0200 Subject: [PATCH 4/7] pull up cass_read when tape is not running --- cores/c64/rtl/c1530.vhd | 1 + 1 file changed, 1 insertion(+) diff --git a/cores/c64/rtl/c1530.vhd b/cores/c64/rtl/c1530.vhd index 7146113..58951b2 100644 --- a/cores/c64/rtl/c1530.vhd +++ b/cores/c64/rtl/c1530.vhd @@ -129,6 +129,7 @@ begin tap_fifo_rdreq <= '0'; if playing = '0' then + cass_read <= '1'; tap_fifo_error <= '0'; wave_cnt <= (others => '0'); wave_len <= (others => '0'); From 02ef4616b72cfea912d7bdbbb2eccd439fb64c98 Mon Sep 17 00:00:00 2001 From: nino-porcino Date: Wed, 17 Apr 2019 17:15:24 +0200 Subject: [PATCH 5/7] extend pull up of cass_read to EAR input --- cores/c64/rtl/c1530.vhd | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cores/c64/rtl/c1530.vhd b/cores/c64/rtl/c1530.vhd index 58951b2..a8b314c 100644 --- a/cores/c64/rtl/c1530.vhd +++ b/cores/c64/rtl/c1530.vhd @@ -126,10 +126,13 @@ begin end if; playing <= (not cass_motor) and (not sense) and (not ear_input_detected); -- cass_motor and sense are low active + + if playing = '0' and ear_input_detected = '0' then + cass_read <= '1'; + end if; tap_fifo_rdreq <= '0'; - if playing = '0' then - cass_read <= '1'; + if playing = '0' then tap_fifo_error <= '0'; wave_cnt <= (others => '0'); wave_len <= (others => '0'); @@ -141,7 +144,7 @@ begin -- Wav player required a large depth fifo to give chance -- fifo not falling empty while host go reading next sd card sector - -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) + -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) wav_player_tick_cnt <= wav_player_tick_cnt + '1'; From d8a1bfce9654036139ab0c769a8d073d84f296ef Mon Sep 17 00:00:00 2001 From: nino-porcino Date: Wed, 17 Apr 2019 21:14:57 +0200 Subject: [PATCH 6/7] do not reset pulse counters when playing is paused --- cores/c64/rtl/c1530.vhd | 7 ------- 1 file changed, 7 deletions(-) diff --git a/cores/c64/rtl/c1530.vhd b/cores/c64/rtl/c1530.vhd index a8b314c..2646c98 100644 --- a/cores/c64/rtl/c1530.vhd +++ b/cores/c64/rtl/c1530.vhd @@ -132,13 +132,6 @@ begin end if; tap_fifo_rdreq <= '0'; - if playing = '0' then - tap_fifo_error <= '0'; - wave_cnt <= (others => '0'); - wave_len <= (others => '0'); - tap_player_tick_cnt <= (others => '0'); - wav_player_tick_cnt <= (others => '0'); - end if; if (playing = '1') and (wav_mode = '1') then From f54d7f07435797203d2ad9dbeab82b7587a7c829 Mon Sep 17 00:00:00 2001 From: nino-porcino Date: Wed, 17 Apr 2019 21:16:47 +0200 Subject: [PATCH 7/7] fix typo in comment --- cores/c64/rtl/c1530.vhd | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/c64/rtl/c1530.vhd b/cores/c64/rtl/c1530.vhd index 2646c98..d6eee21 100644 --- a/cores/c64/rtl/c1530.vhd +++ b/cores/c64/rtl/c1530.vhd @@ -137,7 +137,7 @@ begin -- Wav player required a large depth fifo to give chance -- fifo not falling empty while host go reading next sd card sector - -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) + -- (fifo is read every ~22µs, host have to be faster than 11ms to read sd sector) wav_player_tick_cnt <= wav_player_tick_cnt + '1'; @@ -166,7 +166,7 @@ begin -- if ((tap_player_tick_cnt = "100000") and (skip_bytes = '0')) then -- divide by 33 if ((tap_player_tick_cnt = "011111") and (skip_bytes = '0')) then -- divide by 32 - -- square wave period (1/2 duty cycle not mendatory, only falling edge matter) + -- square wave period (1/2 duty cycle not mandatory, only falling edge matter) if wave_cnt > '0' & wave_len(10 downto 1) then cass_read <= '1'; else