1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-04 23:24:39 +00:00

C16: update C1541 from C64

This commit is contained in:
Gyorgy Szombathelyi
2020-05-17 21:38:02 +02:00
parent 798a238686
commit b136cdf026
4 changed files with 118 additions and 85 deletions

View File

@@ -170,14 +170,15 @@ begin
uc1_ca1_i <= not sb_atn_in;
-- PA
uc1_pa_i(0) <= tr00_sense_n;
uc1_pa_i(7 downto 1) <= (others => '0'); -- NC
uc1_pa_i(7 downto 1) <= (others => '1'); -- NC
-- PB
uc1_pb_i(0) <= not (sb_data_in and sb_data_oe);
sb_data_oe <= not (uc1_pb_o(1) or uc1_pb_oe_n(1)) and not atn;
uc1_pb_i(1) <= '1';
sb_data_oe <= not (uc1_pb_o(1) or uc1_pb_oe_n(1)) and not atn;
uc1_pb_i(2) <= not (sb_clk_in and sb_clk_oe);
sb_clk_oe <= not (uc1_pb_o(3) or uc1_pb_oe_n(3));
sb_clk_oe <= not (uc1_pb_o(3) or uc1_pb_oe_n(3));
uc1_pb_i(4 downto 3) <= "11"; -- NC
atna <= uc1_pb_o(4) or uc1_pb_oe_n(4);
uc1_pb_i(6 downto 5) <= DEVICE_SELECT xor ds; -- allows override
uc1_pb_i(7) <= not sb_atn_in;
@@ -314,10 +315,10 @@ begin
port_b_i => uc1_pb_i,
ca1_i => uc1_ca1_i,
ca2_i => '0',
ca2_i => '1',
cb1_i => '0',
cb2_i => '0',
cb1_i => '1',
cb2_i => '1',
irq => uc1_irq
);
@@ -353,13 +354,13 @@ begin
ca1_i => uc3_ca1_i,
ca2_o => uc3_ca2_o,
ca2_i => '0',
ca2_i => '1',
ca2_t => uc3_ca2_oe,
cb1_i => '0',
cb1_i => '1',
cb2_o => uc3_cb2_o,
cb2_i => '0',
cb2_i => '1',
cb2_t => uc3_cb2_oe,
irq => uc3_irq

View File

@@ -199,7 +199,7 @@ port map
mode => mode, -- read/write
-- stp => stp, -- stepper motor control
mtr => mtr, -- stepper motor on/off
-- freq => freq, -- motor (gcr_bit) frequency
freq => freq, -- motor (gcr_bit) frequency
sync_n => sync_n, -- reading SYNC bytes
byte_n => byte_n, -- byte ready

View File

@@ -24,7 +24,7 @@ port(
mode : in std_logic; -- read/write
-- stp : in std_logic_vector(1 downto 0); -- stepper motor control
mtr : in std_logic; -- stepper motor on/off
-- freq : in std_logic_vector(1 downto 0); -- motor (gcr_bit) frequency
freq : in std_logic_vector(1 downto 0); -- motor (gcr_bit) frequency
sync_n : out std_logic; -- reading SYNC bytes
byte_n : out std_logic; -- byte ready
@@ -43,6 +43,7 @@ end gcr_floppy;
architecture struct of gcr_floppy is
signal bit_clk_en : std_logic;
signal bit_clk_div : std_logic_vector(7 downto 0);
signal sync_cnt : std_logic_vector(5 downto 0) := (others => '0');
signal byte_cnt : std_logic_vector(8 downto 0) := (others => '0');
signal nibble : std_logic := '0';
@@ -134,7 +135,7 @@ with nibble select
gcr_bit <= gcr_nibble(to_integer(unsigned(gcr_bit_cnt)));
sector_max <= "10100" when track_num < std_logic_vector(to_unsigned(18,6)) else
sector_max <= "10100" when track_num < std_logic_vector(to_unsigned(18,6)) else
"10010" when track_num < std_logic_vector(to_unsigned(25,6)) else
"10001" when track_num < std_logic_vector(to_unsigned(31,6)) else
"10000" ;
@@ -158,27 +159,33 @@ with gcr_nibble_out select
X"D" when "11101",--"10111",
X"E" when "11110",--"01111",
X"F" when others; --"10101",
with freq select
bit_clk_div <= x"67" when "11",
x"6F" when "10",
x"77" when "01",
x"7F" when others;
process (clk32)
variable bit_clk_cnt : std_logic_vector(7 downto 0) := (others => '0');
begin
if rising_edge(clk32) then
mode_r1 <= mode;
if (mode_r1 xor mode) = '1' then -- read <-> write change
bit_clk_cnt := (others => '0');
byte_n <= '1';
bit_clk_en <= '0';
else
bit_clk_en <= '0';
if bit_clk_cnt = X"6F" then
if bit_clk_cnt = bit_clk_div then
bit_clk_en <= '1';
bit_clk_cnt := (others => '0');
else
bit_clk_cnt := bit_clk_cnt + '1';
end if;
byte_n <= '1';
if byte_in_n = '0' and mtr = '1' and ram_ready = '1' then
if bit_clk_cnt > X"10" then
@@ -187,9 +194,7 @@ begin
end if;
end if;
end if;
end if;
end if;
end process;
@@ -201,11 +206,11 @@ begin
if old_track /= track_num then
sector <= (others => '0'); --reset sector number on track change
else if bit_clk_en = '1' then
elsif bit_clk_en = '1' then
mode_r2 <= mode;
if mode = '1' then autorise_write <= '0'; end if;
if (mode xor mode_r2) = '1' then
if mode = '1' then -- leaving write mode
sync_in_n <= '0';
@@ -220,9 +225,9 @@ begin
data_cks <= (others => '0');
end if;
end if;
if sync_in_n = '0' and mode = '1' then
byte_cnt <= (others => '0');
nibble <= '0';
gcr_bit_cnt <= (others => '0');
@@ -230,18 +235,18 @@ begin
c1541_logic_din <= (others => '0');
gcr_byte <= (others => '0');
data_cks <= (others => '0');
if sync_cnt = X"31" then
sync_cnt <= (others => '0');
sync_in_n <= '1';
else
sync_cnt <= sync_cnt + '1';
end if;
end if;
if sync_in_n = '1' or mode = '0' then
gcr_bit_cnt <= gcr_bit_cnt + '1';
if gcr_bit_cnt = X"4" then
gcr_bit_cnt <= (others => '0');
@@ -292,17 +297,17 @@ begin
end if;
end if;
end if;
-- demux byte from floppy (ram)
gcr_byte <= gcr_byte(6 downto 0) & gcr_bit;
if bit_cnt = X"7" then
c1541_logic_din <= gcr_byte(6 downto 0) & gcr_bit;
end if;
-- serialise/convert byte to floppy (ram)
gcr_nibble_out <= gcr_nibble_out(3 downto 0) & gcr_bit_out;
if gcr_bit_cnt = X"0" then
if nibble = '0' then
ram_di(3 downto 0) <= nibble_out;
@@ -318,11 +323,10 @@ begin
else
ram_we <= '0';
end if;
end if;
end if;
end if;
end if;
end process;
end struct;

View File

@@ -97,8 +97,11 @@ architecture Gideon of via6522 is
signal serport_en : std_logic;
signal ser_cb2_o : std_logic;
signal hs_cb2_o : std_logic;
signal trigger_serial: std_logic;
signal cb1_t_int : std_logic;
signal cb1_o_int : std_logic;
signal cb2_t_int : std_logic;
signal cb2_o_int : std_logic;
alias ca2_event : std_logic is irq_events(0);
alias ca1_event : std_logic is irq_events(1);
alias serial_event : std_logic is irq_events(2);
@@ -137,7 +140,8 @@ architecture Gideon of via6522 is
alias ca1_edge_select : std_logic is pcr(0);
signal ira, irb : std_logic_vector(7 downto 0) := (others => '0');
signal write_t1c_l : std_logic;
signal write_t1c_h : std_logic;
signal write_t2c_h : std_logic;
@@ -154,6 +158,7 @@ architecture Gideon of via6522 is
begin
irq <= irq_out;
write_t1c_l <= '1' when (addr = X"4" or addr = x"6") and wen='1' and falling = '1' else '0';
write_t1c_h <= '1' when addr = X"5" and wen='1' and falling = '1' else '0';
write_t2c_h <= '1' when addr = X"9" and wen='1' and falling = '1' else '0';
@@ -163,8 +168,13 @@ begin
cb2_event <= (cb2_c xor cb2_d) and (cb2_d xor cb2_edge_select);
ca2_t <= ca2_is_output;
cb2_t <= cb2_is_output when serport_en='0' else shift_dir;
cb2_o <= hs_cb2_o when serport_en='0' else ser_cb2_o;
cb2_t_int <= cb2_is_output when serport_en='0' else shift_dir;
cb2_o_int <= hs_cb2_o when serport_en='0' else ser_cb2_o;
cb1_t <= cb1_t_int;
cb1_o <= cb1_o_int;
cb2_t <= cb2_t_int;
cb2_o <= cb2_o_int;
with ca2_out_mode select ca2_o <=
ca2_handshake_o when "00",
@@ -205,8 +215,16 @@ begin
-- CA1/CA2/CB1/CB2 edge detect flipflops
ca1_c <= To_X01(ca1_i);
ca2_c <= To_X01(ca2_i);
cb1_c <= To_X01(cb1_i);
cb2_c <= To_X01(cb2_i);
if cb1_t_int = '0' then
cb1_c <= To_X01(cb1_i);
else
cb1_c <= cb1_o_int;
end if;
if cb2_t_int = '0' then
cb2_c <= To_X01(cb2_i);
else
cb2_c <= cb2_o_int;
end if;
ca1_d <= ca1_c;
ca2_d <= ca2_c;
@@ -259,10 +277,6 @@ begin
-- Interrupt logic
irq_flags <= irq_flags or irq_events;
if falling = '1' then
trigger_serial <= '0';
end if;
-- Writes --
if wen='1' and falling = '1' then
last_data <= data_in;
@@ -309,9 +323,6 @@ begin
when X"A" => -- Serial port
serial_flag <= '0';
if shift_active = '0' then
trigger_serial <= '1';
end if;
when X"B" => -- ACR (Auxiliary Control Register)
acr <= data_in;
@@ -343,6 +354,9 @@ begin
when X"0" => -- ORB
--Port B reads its own output register for pins set to output.
data_out <= (pio_i.prb and pio_i.ddrb) or (irb and not pio_i.ddrb);
if tmr_a_output_en='1' then
data_out(7) <= timer_a_out;
end if;
when X"1" => -- ORA
data_out <= ira;
when X"2" => -- DDRB
@@ -400,7 +414,6 @@ begin
when X"A" => -- SR
serial_flag <= '0';
trigger_serial <= '1';
when others =>
null;
@@ -419,7 +432,6 @@ begin
cb2_pulse_o <= '1';
timer_a_latch <= latch_reset_pattern;
timer_b_latch <= latch_reset_pattern;
trigger_serial <= '0';
end if;
end if;
end process;
@@ -437,8 +449,8 @@ begin
-- Timer A
tmr_a: block
signal timer_a_reload : std_logic;
signal timer_a_oneshot_trig : std_logic;
signal timer_a_toggle : std_logic;
signal timer_a_may_interrupt : std_logic;
begin
process(clock)
begin
@@ -448,8 +460,11 @@ begin
if timer_a_reload = '1' then
timer_a_count <= timer_a_latch;
if write_t1c_l = '1' then
timer_a_count(7 downto 0) <= data_in;
end if;
timer_a_reload <= '0';
timer_a_oneshot_trig <= '0';
timer_a_may_interrupt <= timer_a_may_interrupt and tmr_a_freerun;
else
if timer_a_count = X"0000" then
-- generate an event if we were triggered
@@ -461,29 +476,29 @@ begin
end if;
if rising = '1' then
if timer_a_event = '1' then
if timer_a_event = '1' and tmr_a_output_en = '1' then
timer_a_toggle <= not timer_a_toggle;
end if;
end if;
if write_t1c_h = '1' then
timer_a_toggle <= '0';
timer_a_may_interrupt <= '1';
timer_a_toggle <= not tmr_a_output_en;
timer_a_count <= data_in & timer_a_latch(7 downto 0);
timer_a_reload <= '0';
timer_a_oneshot_trig <= '1';
end if;
if reset='1' then
timer_a_may_interrupt <= '0';
timer_a_toggle <= '1';
timer_a_count <= latch_reset_pattern;
timer_a_reload <= '0';
timer_a_oneshot_trig <= '0';
end if;
end if;
end process;
timer_a_out <= timer_a_toggle;
timer_a_event <= rising and timer_a_reload and (tmr_a_freerun or timer_a_oneshot_trig);
timer_a_event <= rising and timer_a_reload and timer_a_may_interrupt;
end block tmr_a;
@@ -559,41 +574,56 @@ begin
end block tmr_b;
ser: block
signal trigger_serial: std_logic;
signal shift_clock_d : std_logic;
signal shift_clock : std_logic;
signal shift_tick_r : std_logic;
signal shift_tick_f : std_logic;
signal shift_timer_tick : std_logic;
signal cb2_c : std_logic := '0';
signal bit_cnt : integer range 0 to 7;
signal shift_pulse : std_logic;
begin
process(shift_active, timer_b_tick, shift_clk_sel, shift_clock, shift_clock_d)
process(shift_active, timer_b_tick, shift_clk_sel, shift_clock, shift_clock_d, shift_timer_tick)
begin
case shift_clk_sel is
when "10" =>
shift_pulse <= '1';
when "00"|"01" =>
shift_pulse <= timer_b_tick;
shift_pulse <= shift_timer_tick;
when others =>
shift_pulse <= shift_clock and not shift_clock_d;
end case;
if shift_active = '0' then
shift_pulse <= '0';
-- Mode 0 still loads the shift register to external pulse (MMBEEB SD-Card interface uses this)
if shift_mode_control = "000" then
shift_pulse <= shift_clock and not shift_clock_d;
else
shift_pulse <= '0';
end if;
end if;
end process;
process(clock)
begin
if rising_edge(clock) then
cb2_c <= To_X01(cb2_i);
if rising = '1' then
cb2_c <= To_X01(cb2_i);
if shift_active='0' then
shift_clock <= '1';
if shift_mode_control = "000" then
shift_clock <= To_X01(cb1_i);
else
shift_clock <= '1';
end if;
elsif shift_clk_sel = "11" then
shift_clock <= To_X01(cb1_i);
elsif shift_pulse = '1' then
@@ -602,55 +632,53 @@ begin
shift_clock_d <= shift_clock;
if shift_tick_f = '1' then
ser_cb2_o <= shift_reg(7);
end if;
end if;
if falling = '1' then
shift_timer_tick <= timer_b_tick;
end if;
if reset = '1' then
shift_clock <= '1';
shift_clock_d <= '1';
ser_cb2_o <= '1';
end if;
end if;
end process;
cb1_t <= '0' when shift_clk_sel="11" else serport_en;
cb1_o <= shift_clock_d;
cb1_t_int <= '0' when shift_clk_sel="11" else serport_en;
cb1_o_int <= shift_clock_d;
ser_cb2_o <= shift_reg(7);
serport_en <= shift_dir or shift_clk_sel(1) or shift_clk_sel(0);
trigger_serial <= '1' when (ren='1' or wen='1') and addr=x"A" else '0';
shift_tick_r <= not shift_clock_d and shift_clock;
shift_tick_f <= shift_clock_d and not shift_clock;
process(clock)
begin
if rising_edge(clock) then
if reset = '1' then
shift_reg <= X"FF";
shift_tick_r <= '0';
shift_tick_f <= '0';
elsif falling = '1' then
shift_tick_r <= not shift_clock_d and shift_clock;
shift_tick_f <= shift_clock_d and not shift_clock;
if wen = '1' and addr = X"A" then
shift_reg <= data_in;
elsif shift_tick_r = '1' then
if shift_dir='1' then -- output
shift_reg <= shift_reg(6 downto 0) & shift_reg(7);
else
shift_reg <= shift_reg(6 downto 0) & cb2_c;
end if;
elsif shift_dir='1' and shift_tick_f = '1' then -- output
shift_reg <= shift_reg(6 downto 0) & shift_reg(7);
elsif shift_dir='0' and shift_tick_r = '1' then -- input
shift_reg <= shift_reg(6 downto 0) & cb2_c;
end if;
end if;
end if;
end process;
-- tell people that we're ready!
serial_event <= shift_tick_r and not shift_active and rising;
serial_event <= shift_tick_r and not shift_active and rising and serport_en;
process(clock)
begin
if rising_edge(clock) then
if falling = '1' then
if shift_active = '0' then
if shift_active = '0' and shift_mode_control /= "000" then
if trigger_serial = '1' then
bit_cnt <= 7;
shift_active <= '1';
@@ -667,7 +695,7 @@ begin
end if;
end if;
end if;
if reset='1' then
shift_active <= '0';
bit_cnt <= 0;