Minimig Discussion Forum

Discussing the Open Source FPGA Amiga Project
It is currently Sun May 19, 2013 3:13 am

All times are UTC




Post new topic Reply to topic  [ 2 posts ] 
Author Message
 Post subject: Drive rotation emulation on Minimig
PostPosted: Wed Jul 21, 2010 4:09 pm 
Offline

Joined: Sun Jan 04, 2009 3:48 am
Posts: 80
Hello,

to improve compatibility I put in place a floppy rotation emulation.
My floppy module is VHDL not Verilog.
Here is the code snippet for the rotation :

internal signals:
Code:
  -- Disk rotation
  TYPE REV_STATE_TYPE IS
  (
    REV_STATE_IDLE,
    REV_STATE_HDR,
    REV_STATE_DATA,
    REV_STATE_GAP
  );
  SIGNAL rev_state    : REV_STATE_TYPE;
  SIGNAL rev_idle     : STD_LOGIC;
  SIGNAL rev_hdr      : STD_LOGIC;
  SIGNAL rev_data     : STD_LOGIC;
  SIGNAL rev_gap      : STD_LOGIC;
  SIGNAL rev_clk_ctr  : STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL rev_word_ctr : STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL rev_word_gap : STD_LOGIC_VECTOR(7 DOWNTO 0);
  SIGNAL rev_sect_ctr : STD_LOGIC_VECTOR(3 DOWNTO 0);


process:
Code:
  -------------------
  -- Disk rotation --
  -------------------
 
  -- PAL clock  : 7.093750 MHz
  -- NTSC clock : 7.159091 MHz
  -- 224 clocks per 32-bit MFM word
  -- 3167 (PAL) or 3196 (NTSC) 32-bit MFM words per track
  -- 272 32-bit MFM words per sector (header:16, data:256)
  -- End of track gap : 175 (PAL) or 204 (NTSC) 32-bit MFM words

  PROCESS
  (
    reset,        -- Reset signal
    clk,          -- Bus clock
    dsk_sel_n,    -- Disk drive select
    dsk_sel_dly,  -- Disk drive select delayed
    dsk_mtr_n,    -- Disk spinning motor
    drv_mtr,      -- Latched disk spinning state
    drv_ena,      -- Drive enabled
    rev_state,    -- Disk rotation state
    rev_clk_ctr,  -- Clock counter
    rev_word_ctr, -- Long word counter
    rev_word_gap, -- Number of long words in a track gap
    rev_sect_ctr  -- Sector counter
  )
  BEGIN
    IF (reset = '1') THEN
      dsk_sel_dly  <= "1111";
      drv_mtr      <= "0000";
      rev_clk_ctr  <= X"00";
      rev_word_ctr <= X"00";
      rev_sect_ctr <= X"0";
      rev_state    <= REV_STATE_IDLE;
    ELSIF (rising_edge(clk)) THEN
      -- Drives motors latches
      dsk_sel_dly <= dsk_sel_n;
      FOR i IN 0 TO 3 LOOP
        IF (dsk_sel_n(i) = '0') AND (dsk_sel_dly(i) = '1') THEN
          drv_mtr(i) <= (NOT dsk_mtr_n) AND drv_ena(i);
        END IF;
      END LOOP;
      -- Disk rotation state machine
      IF (rev_clk_ctr = X"DF") THEN
        CASE rev_state IS
          -- Spinning motor OFF
          WHEN REV_STATE_IDLE =>
            rev_word_ctr <= X"00";
            rev_sect_ctr <= X"0";
            -- Spinning motor ON
            IF (drv_mtr /= "0000") THEN
              rev_state <= REV_STATE_HDR;
            END IF;
          -- Sector header
          WHEN REV_STATE_HDR =>
            IF (drv_mtr = "0000") THEN
              -- Spinning motor OFF
              rev_word_ctr <= X"00";
              rev_sect_ctr <= X"0";
              rev_state <= REV_STATE_IDLE;
            ELSE
              IF (rev_word_ctr = X"0F") THEN
                -- Sector data after 16 long words
                rev_word_ctr <= X"00";
                rev_state <= REV_STATE_DATA;
              ELSE
                rev_word_ctr <= rev_word_ctr + '1';
              END IF;
            END IF;
          -- Sector data
          WHEN REV_STATE_DATA =>
            IF (drv_mtr = "0000") THEN
              -- Spinning motor OFF
              rev_word_ctr <= X"00";
              rev_sect_ctr <= X"0";
              rev_state <= REV_STATE_IDLE;
            ELSE
              rev_word_ctr <= rev_word_ctr + '1';
              IF (rev_word_ctr = X"FF") THEN
                IF (rev_sect_ctr = X"A") THEN
                  -- Track gap after 256 long words and sector #10
                  rev_sect_ctr <= X"F";
                  rev_state <= REV_STATE_GAP;
                ELSE
                  -- Next sector header after 256 long words
                  rev_sect_ctr <= rev_sect_ctr + '1';
                  rev_state <= REV_STATE_HDR;
                END IF;
              END IF;
            END IF;
          -- Track gap
          WHEN REV_STATE_GAP =>
            IF (drv_mtr = "0000") THEN
              -- Spinning motor OFF
              rev_word_ctr <= X"00";
              rev_sect_ctr <= X"0";
              rev_state <= REV_STATE_IDLE;
            ELSE
              IF (rev_word_ctr = rev_word_gap) THEN
                -- Sector #0 header after track gap
                rev_word_ctr <= X"00";
                rev_sect_ctr <= X"0";
                rev_state <= REV_STATE_HDR;
              ELSE
                rev_word_ctr <= rev_word_ctr + '1';
              END IF;
            END IF;
          WHEN OTHERS =>
            rev_clk_ctr  <= X"00";
            rev_word_ctr <= X"00";
            rev_sect_ctr <= X"0";
            rev_state    <= REV_STATE_IDLE;
        END CASE;
        rev_clk_ctr <= X"00";
      ELSE
        rev_clk_ctr <= rev_clk_ctr + '1';
      END IF;
    END IF;
  END PROCESS;

  -- Disk LED is ON if at least one motor is ON
  dsk_led <= '1' WHEN (drv_mtr /= "0000") ELSE '0';
  -- Disk index is ON at the end of the track gap (1.5 ms duration)
  dsk_idx <= (rev_word_ctr(7) AND rev_gap);


"rev_word_gap" has to be set to 174 or 203 depending if you use a PAL (28.375160 MHz) or NTSC (28.636363 MHz) clock.
maybe, somebody can port it back to the original Minimig code. Yaqube, maybe ?

Regards,

Frederic


Top
 Profile  
 
 Post subject: Re: Drive rotation emulation on Minimig
PostPosted: Tue Aug 03, 2010 3:33 pm 
Offline

Joined: Mon Dec 01, 2008 6:41 pm
Posts: 161
Can I ask which games this fixes and dose it help to improve adf write emulation or is that just a limitation of the adf format we are stuck with?

_________________
2MB Minimig with PIC
4MB Minimig with ARM Addon board


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 2 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Translated by Xaphos © 2007, 2008, 2009 phpBB.fr