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:
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user