1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-06 08:04:41 +00:00

refactor tape, add EAR/MIC support

This commit is contained in:
Antonino Porcino
2019-04-16 18:54:10 +02:00
parent af4fe5a9bb
commit 0abc502d90
3 changed files with 111 additions and 81 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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