From e57573891993e0722145786060b0fc2feb4bfe76 Mon Sep 17 00:00:00 2001 From: byrtolet Date: Sun, 14 Oct 2018 16:29:02 +0300 Subject: [PATCH] semiworking dos --- cores/Oric/build/ORIC.prj | 8 +- cores/Oric/source/controller_8dos.vhd | 155 +++++++++++++++++++------- cores/Oric/source/disk_ii.vhd | 123 ++++++++++++-------- cores/Oric/source/oric_zxuno_my.ucf | 7 ++ cores/Oric/source/ram48k.vhd | 23 ++-- cores/Oric/source/scan_converter.vhd | 2 +- cores/Oric/source/spi_controller.vhd | 23 +++- 7 files changed, 235 insertions(+), 106 deletions(-) diff --git a/cores/Oric/build/ORIC.prj b/cores/Oric/build/ORIC.prj index 84d9404..53be505 100644 --- a/cores/Oric/build/ORIC.prj +++ b/cores/Oric/build/ORIC.prj @@ -9,7 +9,8 @@ vhdl work "../source/YM2149_linmix.vhd" vhdl work "../source/ula.vhd" vhdl work "../source/T65/T65.vhd" vhdl work "../source/scan_converter.vhd" -vhdl work "../source/rom_oa.vhd" +vhdl work "../source/pravetz.vhd" +#vhdl work "../source/rom_oa.vhd" vhdl work "../source/ram48k.vhd" vhdl work "../source/m6522.vhd" vhdl work "../source/keyboard/keyboard.vhd" @@ -21,5 +22,6 @@ vhdl work "../source/onebitadc.vhd" vhdl work "../source/clkdiv.vhd" vhdl work "../source/controller_8dos.vhd" vhdl work "../source/dos8rom.vhd" -#vhdl work "../source/spi_controller.vhd" -#vhdl work "../source/disk_ii.vhd" +vhdl work "../source/spi_controller.vhd" +vhdl work "../source/disk_ii.vhd" +vhdl work "../source/debounce.vhd" \ No newline at end of file diff --git a/cores/Oric/source/controller_8dos.vhd b/cores/Oric/source/controller_8dos.vhd index 3af58d2..ec3b39b 100644 --- a/cores/Oric/source/controller_8dos.vhd +++ b/cores/Oric/source/controller_8dos.vhd @@ -15,7 +15,24 @@ entity controller_8dos is O_MAPn : out std_logic; A : in std_logic_vector(15 downto 0); D_IN : in std_logic_vector(7 downto 0); -- From 6502 - D_OUT : out std_logic_vector(7 downto 0) -- To 6502 + D_OUT : out std_logic_vector(7 downto 0); -- To 6502 + + -- indication + disk_a_on : out std_logic; + disk_cur_TRACK: out std_logic_vector(5 downto 0); -- Current track (0-34) + disk_track_addr: out std_logic_vector(13 downto 0); + IMAGE_NUMBER_out : out std_logic_vector(9 downto 0); + track_ok : out std_logic; -- 0 when disk is active else 1 + + IMAGE_UP :in std_logic; + IMAGE_DOWN :in std_logic; + + -- sd card + SD_DAT : in std_logic; + SD_DAT3 : out std_logic; + SD_CMD : out std_logic; + SD_CLK : out std_logic + ); end controller_8dos; @@ -25,12 +42,55 @@ architecture imp of controller_8dos is signal s_extension: std_logic; signal rom_out: std_logic_vector(7 downto 0); signal IO_CONTROLn_int : std_logic; + signal disk_select : std_logic; signal CUR_PHI_2:std_logic; signal OLD_PHI_2:std_logic; signal rising_PHI_2:std_logic; signal falling_PHI_2:std_logic; -begin + signal disk_D_OUT : std_logic_vector(7 downto 0); + -- connection between spi_controller & disk_ii + signal IMAGE_NUMBER : unsigned(9 downto 0); + signal TRACK : unsigned(5 downto 0); + signal TRACK_ADDR : unsigned(13 downto 0); + signal TRACK_RAM_ADDR : unsigned(13 downto 0); + signal TRACK_RAM_DI : unsigned(7 downto 0); + signal TRACK_RAM_WE : std_logic; + signal TRACK_GOOD: std_logic; + -- + signal D1_ACTIVE, D2_ACTIVE : std_logic; + + signal IMAGE_UP_old : std_logic; + signal IMAGE_DOWN_old : std_logic; + signal IMAGE_UP_cur : std_logic; + signal IMAGE_DOWN_cur : std_logic; + +begin + IMAGE_NUMBER_OUT <= std_logic_vector(IMAGE_NUMBER); + + imgnum:process (CLK_24) + constant maxcount:integer := 1000000000; + begin + if (rising_edge(CLK_24)) then + if (RESETn = '0') then + IMAGE_NUMBER <= "0000000000"; + else + + IMAGE_UP_old <= IMAGE_UP_cur; + IMAGE_UP_cur <= IMAGE_UP; + IMAGE_DOWN_old <= IMAGE_DOWN_cur; + IMAGE_DOWN_cur <= IMAGE_DOWN; + if (IMAGE_UP_cur = '0' and IMAGE_UP_old = '1') then + IMAGE_NUMBER <= IMAGE_NUMBER + 1; + end if; + if (IMAGE_DOWN_cur = '0' and IMAGE_DOWN_old = '1') and IMAGE_NUMBER >0 then + IMAGE_NUMBER <= IMAGE_NUMBER - 1; + end if; + end if; + end if; + end process; + + -- PHI_2 edges phi_2_edges: process(CLK_24) begin @@ -44,11 +104,16 @@ begin --IO_CONTROL_SIGNAL - IO_CONTROLn_int <= '0' - when (A(15 downto 8) = x"03") + IO_CONTROLn_int <= '0' when (A(15 downto 8) = x"03") and (A(7 downto 4) /= x"0") and (IO_SELECTn = '0') else '1'; + --disk_select signal + disk_select <= '1' when (A(15 downto 8) = x"03") + and (A(7 downto 4) = x"1") + and (IO_SELECTn = '0') + else '0'; + IO_CONTROLn <= IO_CONTROLn_int; s_romdis <= '1'; O_ROMDISn <= s_romdis; @@ -96,47 +161,55 @@ begin dout => rom_out ); - D_OUT <= rom_out; +-- multiplex output + D_OUT <= rom_out when disk_select = '0' else disk_D_OUT; - -- disk : entity work.disk_ii port map ( - -- CLK_14M => CLK_14M, - -- CLK_2M => CLK_2M, - -- PRE_PHASE_ZERO => PRE_PHASE_ZERO, - -- IO_SELECT => IO_SELECT(6), - -- DEVICE_SELECT => DEVICE_SELECT(6), - -- RESET => reset, - -- A => ADDR, - -- D_IN => D, - -- D_OUT => PD, - -- TRACK => TRACK, - -- TRACK_ADDR => TRACK_ADDR, - -- D1_ACTIVE => D1_ACTIVE, - -- D2_ACTIVE => D2_ACTIVE, - -- ram_write_addr => TRACK_RAM_ADDR, - -- ram_di => TRACK_RAM_DI, - -- ram_we => TRACK_RAM_WE - -- ); - -- sdcard_interface : entity work.spi_controller port map ( - -- CLK_14M => CLK_14M, - -- RESET => RESET, +-- indication + disk_a_on <= not D1_ACTIVE; - -- CS_N => CS_N, - -- MOSI => MOSI, - -- MISO => MISO, - -- SCLK => SCLK, + track_ok <= not TRACK_GOOD; + + disk : entity work.disk_ii port map ( + CLK => CLK_24, + PHI_2 => PHI_2, + DEVICE_SELECT => disk_select, + RESETn => RESETn, + A => A(3 downto 0), + D_IN => D_IN, + D_OUT => disk_D_OUT, + -- sd card + D1_ACTIVE => D1_ACTIVE, -- drive 1 on + D2_ACTIVE => D2_ACTIVE, -- drive 2 on + + -- to spi_controler + TRACK => TRACK, -- current track to read + TRACK_ADDR => TRACK_ADDR, -- current track_address + ram_write_addr => TRACK_RAM_ADDR, + ram_di => TRACK_RAM_DI, + ram_we => TRACK_RAM_WE, + TRACK_GOOD => TRACK_GOOD + ); + + disk_cur_TRACK <= std_logic_vector(TRACK); + disk_track_addr <= std_logic_vector(TRACK_ADDR); + sdcard_interface : entity work.spi_controller port map ( + CLK_14M => CLK_24, + RESETn => RESETn, + + CS_N => SD_DAT3, + MOSI => SD_CMD, + MISO => SD_DAT, + SCLK => SD_CLK, - -- track => TRACK, - -- image => image, - - -- ram_write_addr => TRACK_RAM_ADDR, - -- ram_di => TRACK_RAM_DI, - -- ram_we => TRACK_RAM_WE - -- ); + track => TRACK, + image => IMAGE_NUMBER, + TRACK_GOOD => TRACK_GOOD, - -- SD_DAT3 <= CS_N; - -- SD_CMD <= MOSI; - -- MISO <= SD_DAT; - -- SD_CLK <= SCLK; + -- from diskii + ram_write_addr => TRACK_RAM_ADDR, + ram_di => TRACK_RAM_DI, + ram_we => TRACK_RAM_WE + ); end imp; diff --git a/cores/Oric/source/disk_ii.vhd b/cores/Oric/source/disk_ii.vhd index 8497abf..0119f24 100644 --- a/cores/Oric/source/disk_ii.vhd +++ b/cores/Oric/source/disk_ii.vhd @@ -68,22 +68,22 @@ use ieee.numeric_std.all; entity disk_ii is port ( - CLK_14M : in std_logic; - CLK_2M : in std_logic; - PRE_PHASE_ZERO : in std_logic; - IO_SELECT : in std_logic; -- e.g., C600 - C6FF ROM + CLK : in std_logic; + PHI_2 : in std_logic; DEVICE_SELECT : in std_logic; -- e.g., C0E0 - C0EF I/O locations - RESET : in std_logic; - A : in unsigned(15 downto 0); - D_IN : in unsigned(7 downto 0); -- From 6502 - D_OUT : out unsigned(7 downto 0); -- To 6502 + RESETn : in std_logic; + A : in std_logic_vector(3 downto 0); + D_IN : in std_logic_vector(7 downto 0); -- From 6502 + D_OUT : out std_logic_vector(7 downto 0); -- To 6502 TRACK : out unsigned(5 downto 0); -- Current track (0-34) track_addr : out unsigned(13 downto 0); D1_ACTIVE : out std_logic; -- Disk 1 motor on D2_ACTIVE : out std_logic; -- Disk 2 motor on ram_write_addr : in unsigned(13 downto 0); -- Address for track RAM ram_di : in unsigned(7 downto 0); -- Data to track RAM - ram_we : in std_logic -- RAM write enable + ram_we : in std_logic; -- RAM write enable + TRACK_GOOD : in std_logic -- True when the track is read + -- by spi ); end disk_ii; @@ -103,9 +103,14 @@ architecture rtl of disk_ii is -- Storage for one track worth of data in "nibblized" form type track_ram is array(0 to 6655) of unsigned(7 downto 0); +-- type track_ram is array(0 to 2655) of unsigned(7 downto 0); -- Double-ported RAM for holding a track signal track_memory : track_ram; - signal ram_do : unsigned(7 downto 0); + +attribute ram_style: string; +attribute ram_style of track_memory : signal is "block"; --"distributed"; + + signal ram_do : std_logic_vector(7 downto 0); -- Lower bit indicates whether disk data is "valid" or not -- RAM address is track_byte_addr(14 downto 1) @@ -114,22 +119,35 @@ architecture rtl of disk_ii is -- not yet ready. signal track_byte_addr : unsigned(14 downto 0); signal read_disk : std_logic; -- When C08C accessed - + signal CUR_PHI_2:std_logic; + signal OLD_PHI_2:std_logic; + signal rising_PHI_2:std_logic; + signal falling_PHI_2:std_logic; begin - - interpret_io : process (CLK_2M) + -- PHI_2 edges + phi_2_edges: process(CLK) begin - if rising_edge(CLK_2M) then - if reset = '1' then - motor_phase <= (others => '0'); - drive_on <= '0'; - drive2_select <= '0'; - q6 <= '0'; - q7 <= '0'; - else - if PRE_PHASE_ZERO = '1' and DEVICE_SELECT = '1' then + if (rising_edge(CLK))then + OLD_PHI_2 <= CUR_PHI_2; + CUR_PHI_2 <= PHI_2; + end if; + end process; + rising_PHI_2 <= CUR_PHI_2 and not OLD_PHI_2; + falling_PHI_2<= not CUR_PHI_2 and CUR_PHI_2; + + interpret_io : process (CLK,RESETn) + begin + if RESETn = '0' then + motor_phase <= (others => '0'); + drive_on <= '0'; + drive2_select <= '0'; + q6 <= '0'; + q7 <= '0'; + else + if rising_edge(CLK) then + if DEVICE_SELECT = '1' and rising_PHI_2 = '1' then if A(3) = '0' then -- C080 - C087 - motor_phase(TO_INTEGER(A(2 downto 1))) <= A(0); + motor_phase(TO_INTEGER(unsigned(A(2 downto 1)))) <= A(0); else case A(2 downto 1) is when "00" => drive_on <= A(0); -- C088 - C089 @@ -165,15 +183,15 @@ begin -- 0 1 2 3 0 -- - update_phase : process (CLK_14M) + update_phase : process (CLK, RESETn) variable phase_change : integer; variable new_phase : integer; variable rel_phase : std_logic_vector(3 downto 0); begin - if rising_edge(CLK_14M) then - if reset = '1' then - phase <= TO_UNSIGNED(70, 8); -- Deliberately odd to test reset - else + if RESETn = '0' then + phase <= TO_UNSIGNED(138, 8); -- Deliberately odd to test reset + else + if rising_edge(CLK) then phase_change := 0; new_phase := TO_INTEGER(phase); rel_phase := motor_phase; @@ -223,7 +241,7 @@ begin when others => null; end case; end if; - + if new_phase + phase_change <= 0 then new_phase := 0; elsif new_phase + phase_change > 139 then @@ -239,28 +257,28 @@ begin TRACK <= phase(7 downto 2); -- Dual-ported RAM holding the contents of the track - track_storage : process (CLK_14M) + track_storage : process (CLK) begin - if rising_edge(CLK_14M) then + if rising_edge(CLK) then if ram_we = '1' then track_memory(to_integer(ram_write_addr)) <= ram_di; end if; - ram_do <= track_memory(to_integer(track_byte_addr(14 downto 1))); + ram_do <= std_logic_vector(track_memory(to_integer(track_byte_addr(14 downto 1)))); end if; end process; -- Go to the next byte when the disk is accessed or if the counter times out - read_head : process (CLK_2M) - variable byte_delay : unsigned(5 downto 0); -- Accounts for disk spin rate + read_head : process (CLK) + variable byte_delay : unsigned(8 downto 0); -- Accounts for disk spin rate begin - if rising_edge(CLK_2M) then - if reset = '1' then + if rising_edge(CLK) then + if RESETn = '0' then track_byte_addr <= (others => '0'); byte_delay := (others => '0'); else byte_delay := byte_delay - 1; - if (read_disk = '1' and PRE_PHASE_ZERO = '1') or byte_delay = 0 then - byte_delay := (others => '0'); + if (read_disk = '1' and rising_PHI_2 = '1') then --or byte_delay = 0 then + byte_delay := "000000100"; if track_byte_addr = X"33FE" then track_byte_addr <= (others => '0'); else @@ -271,17 +289,26 @@ begin end if; end process; - rom : entity work.disk_ii_rom port map ( - addr => A(7 downto 0), - clk => CLK_14M, - dout => rom_dout); - - read_disk <= '1' when DEVICE_SELECT = '1' and A(3 downto 0) = x"C" else + read_disk <= '1' when DEVICE_SELECT = '1' and q7 = '0' and q6 = '0' and A(0) = '0' else '0'; -- C08C - - D_OUT <= rom_dout when IO_SELECT = '1' else - ram_do when read_disk = '1' and track_byte_addr(0) = '0' else - (others => '0'); + write_d_out:process(CLK) + begin + D_OUT <= (others => '0'); + if rising_edge(CLK) then + if read_disk = '1' and track_byte_addr(0) = '0' and TRACK_GOOD = '1' and DRIVE_ON ='1' then + D_OUT <= ram_do; + else if (q6 = '1') then + if (DRIVE_ON = '1')then + D_OUT <= x"20"; + else + D_OUT <= x"00"; + end if; + end if; + end if; + end if; + end process; + + track_addr <= track_byte_addr(14 downto 1); diff --git a/cores/Oric/source/oric_zxuno_my.ucf b/cores/Oric/source/oric_zxuno_my.ucf index 642072d..f2cd8a9 100644 --- a/cores/Oric/source/oric_zxuno_my.ucf +++ b/cores/Oric/source/oric_zxuno_my.ucf @@ -131,3 +131,10 @@ NET "SD_DAT" LOC="P117" | IOSTANDARD = LVCMOS33; NET "SD_DAT3" LOC="P121" | IOSTANDARD = LVCMOS33; NET "SD_CMD" LOC="P119" | IOSTANDARD = LVCMOS33; NET "SD_CLK" LOC="P115" | IOSTANDARD = LVCMOS33; + +NET "disk_a_on" LOC="P35" | IOSTANDARD = LVCMOS25; +NET "track_ok" LOC="P34" | IOSTANDARD = LVCMOS25; +NET "image_buton_up" LOC="P112" | IOSTANDARD = LVCMOS25; +NET "image_buton_down" LOC="P114" | IOSTANDARD = LVCMOS25; +#PIN "controller8dos/sdcard_interface/Mmux_spi_clk11.A4" CLOCK_DEDICATED_ROUTE = FALSE; +PIN "inst_buf3.O" CLOCK_DEDICATED_ROUTE = FALSE; \ No newline at end of file diff --git a/cores/Oric/source/ram48k.vhd b/cores/Oric/source/ram48k.vhd index 83d7a9a..60f2ed3 100644 --- a/cores/Oric/source/ram48k.vhd +++ b/cores/Oric/source/ram48k.vhd @@ -38,11 +38,11 @@ begin cs0 <= '1' when cs='1' and addr(15 downto 14)="00" else '0'; cs1 <= '1' when cs='1' and addr(15 downto 14)="01" else '0'; cs2 <= '1' when cs='1' and addr(15 downto 14)="10" else '0'; - cs3 <= '1' when cs='1' and addr(15 downto 14)="11" else '0'; + cs3 <= '1' when cs='1' and addr(14 downto 14)="1" else '0'; do <= ro0 when oe='1' and cs0='1' else - ro1 when oe='1' and cs1='1' else + ro3 when oe='1' and cs3='1' else ro2 when oe='1' and cs2='1' else ro3 when oe='1' and cs3='1' else (others=>'0'); @@ -57,15 +57,16 @@ begin do => ro0 ); - RAM_4000_7FFF : entity work.ram16k - port map ( - clk => clk, - cs => cs1, - we => we, - addr => addr(13 downto 0), - di => di, - do => ro1 - ); + ro1 <= (others => '0'); + -- RAM_4000_7FFF : entity work.ram16k + -- port map ( + -- clk => clk, + -- cs => cs1, + -- we => we, + -- addr => addr(13 downto 0), + -- di => di, + -- do => ro1 + -- ); RAM_8000_BFFF : entity work.ram16k port map ( diff --git a/cores/Oric/source/scan_converter.vhd b/cores/Oric/source/scan_converter.vhd index 3fe6f2c..6c27370 100644 --- a/cores/Oric/source/scan_converter.vhd +++ b/cores/Oric/source/scan_converter.vhd @@ -114,7 +114,7 @@ begin end process; ram_read :process(CLK_x2) begin - if rising_edge(CLK_x2) then + if falling_edge(CLK_x2) then O_VIDEO <= ram(to_integer(unsigned(hpos_o))); end if; end process; diff --git a/cores/Oric/source/spi_controller.vhd b/cores/Oric/source/spi_controller.vhd index 24a6489..3ef1517 100644 --- a/cores/Oric/source/spi_controller.vhd +++ b/cores/Oric/source/spi_controller.vhd @@ -33,9 +33,10 @@ entity spi_controller is ram_we : out std_logic; track : in unsigned(5 downto 0); -- Track number (0-34) image : in unsigned(9 downto 0); -- Which disk image to read + TRACK_GOOD : out std_logic; -- -- System Interface ------------------------------------------------------- CLK_14M : in std_logic; -- System clock - reset : in std_logic + RESETn : in std_logic ); end spi_controller; @@ -127,6 +128,7 @@ begin -- Purpose: -- Implements the combined "SD Card init", "track read" and "command" FSMs. -- + TRACK_GOOD <= '1' when current_track = track and current_image = image and write_addr = TRACK_SIZE else '0'; sd_fsm : process(spi_clk) subtype cmd_t is std_logic_vector(5 downto 0); constant CMD0 : cmd_t := std_logic_vector(to_unsigned(0, 6)); @@ -144,7 +146,7 @@ begin begin if rising_edge(spi_clk) then ram_we <= '0'; - if reset = '1' then + if RESETn = '0' then state <= POWER_UP; -- Deliberately out of range current_track <= (others => '1'); @@ -169,6 +171,21 @@ begin -- SD Card init FSM --------------------------------------------------------------------- when POWER_UP => + current_track <= (others => '1'); + current_image <= (others => '1'); + sclk_sig <= '0'; + slow_clk <= true; + CS_N <= '1'; + command <= (others => '0'); + argument <= (others => '0'); + crc7 <= (others => '0'); + command_out <= (others => '1'); + counter := TO_UNSIGNED(0, 8); + byte_counter := TO_UNSIGNED(0, BLOCK_BITS); + write_addr <= (others => '0'); + high_capacity <= false; + version <= MMC; + lba := (others => '0'); counter := TO_UNSIGNED(224, 8); state <= RAMP_UP; @@ -317,6 +334,8 @@ begin sclk_sig <= '0'; slow_clk <= true; CS_N <= '1'; + state <= POWER_UP; + write_addr <= (others => '0'); --------------------------------------------------------------------- -- Embedded "read track" FSM