Subversion Repositories pentevo

Rev

Rev 896 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

  1. // ZX-Evo Base Configuration (c) NedoPC 2008,2009,2010,2011,2012,2013,2014
  2. //
  3. // vg93 interface
  4.  
  5. /*
  6.     This file is part of ZX-Evo Base Configuration firmware.
  7.  
  8.     ZX-Evo Base Configuration firmware is free software:
  9.     you can redistribute it and/or modify it under the terms of
  10.     the GNU General Public License as published by
  11.     the Free Software Foundation, either version 3 of the License, or
  12.     (at your option) any later version.
  13.  
  14.     ZX-Evo Base Configuration firmware is distributed in the hope that
  15.     it will be useful, but WITHOUT ANY WARRANTY; without even
  16.     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17.     See the GNU General Public License for more details.
  18.  
  19.     You should have received a copy of the GNU General Public License
  20.     along with ZX-Evo Base Configuration firmware.
  21.     If not, see <http://www.gnu.org/licenses/>.
  22. */
  23.  
  24. // #1F - vg93 command/state reg {0,0} - not here!
  25. // #3F - vg93 track register    {0,1} - not here!
  26. // #5F - vg93 sector register   {1,0} - not here!
  27. // #7F - vg93 data register     {1,1} - not here!
  28. // #FF - output "system" reg/input (DRQ+IRQ) reg
  29. //   output: d6 - FM/MFM               - NOT USED ANYWHERE! -> skipped
  30. //           d4 - disk side            - inverted out
  31. //           d3 - head load            - for HRDY pin of vg93
  32. //           d2 - /RESET for vg93      - must be zero at system reset
  33. //           d1:d0 - disk drive select - to the 74138
  34. //    input: d7 - /INTRQ - resynced at CPU clock
  35. //           d6 - /DRQ   - .....................
  36. //
  37. // current limitations:
  38. //  1. read clock regenerator is made of simple counter, as in pentagon128
  39. //  1. write precompensation is based only on SL/SR/TR43 signals
  40.  
  41. `include "../include/tune.v"
  42.  
  43. module vg93(
  44.  
  45.         input zclk, // Z80 cpu clock
  46.         input rst_n,
  47.         input fclk, // fpga 28 MHz clock
  48.  
  49.         output vg_clk,
  50.         output reg vg_res_n,
  51.  
  52.         input [7:0] din,  // data input from CPU
  53.         output intrq,drq, // output signals for the read #FF (not here)
  54.         input vg_wrFF,    // when TRDOS port #FF written - positive strobe
  55.  
  56.  
  57.         output reg  vg_hrdy,
  58.         output wire vg_rclk,
  59.         output wire vg_rawr,
  60.         output reg  [1:0] vg_a, // disk drive selection
  61.         output reg  vg_wrd,
  62.         output reg  vg_side,
  63.  
  64.         input step, // step signal from VG93
  65.         input vg_sl,vg_sr,vg_tr43,
  66.         input rdat_n,
  67.         input vg_wf_de,
  68.         input vg_drq,
  69.         input vg_irq,
  70.         input vg_wd
  71. );
  72.  
  73.  
  74.         localparam WRDELAY_OUTER_LEFT  = 4'd4;
  75.         localparam WRDELAY_OUTER_RIGHT = 4'd11;
  76.         localparam WRDELAY_INNER_LEFT  = 4'd0;  // minimal delay is for maximum shift left
  77.         localparam WRDELAY_INNER_RIGHT = 4'd14; // maximal delay is for maximum shift right
  78.         localparam WRDELAY_STANDARD    = 4'd7;  // no-shift
  79.  
  80.  
  81.  
  82.  
  83.         reg [2:0] vgclk_div7;
  84.         wire vgclk_strobe7;
  85.         reg [1:0] vgclk_div4;
  86.  
  87.         reg [2:0] step_pulse;
  88.         reg [2:0] drq_pulse;
  89.         wire step_pospulse;
  90.         wire  drq_pospulse;
  91.         reg turbo_state;
  92.  
  93.         reg [1:0] intrq_sync;
  94.         reg [1:0] drq_sync;
  95.  
  96.         reg [1:0] sl_sync,sr_sync,tr43_sync;
  97.         reg [2:0] wd_sync;
  98.         wire sl,sr,tr43,wd;
  99.  
  100.         reg [3:0] wrdelay_cnt;
  101.         wire delay_end;
  102.  
  103.         reg [3:0] wrwidth_cnt;
  104.         wire wrwidth_ena;
  105.  
  106.  
  107. //      reg [4:0] rdat_sync;
  108. //      reg rdat_edge1, rdat_edge2;
  109. //      wire rdat;
  110.  
  111. //      reg [3:0] rwidth_cnt;
  112. //      wire rwidth_ena;
  113. //      reg [5:0] rclk_cnt;
  114. //      wire rclk_strobe;
  115.  
  116.  
  117.  
  118.         // VG93 clocking and turbo-mode
  119.  
  120.         always @(posedge fclk)
  121.         begin
  122.                 step_pulse[2:0] <= { step_pulse[1:0], step};
  123.                  drq_pulse[2:0] <= {  drq_pulse[1:0], vg_drq};
  124.         end
  125.  
  126.         assign step_pospulse = ( step_pulse[1] & (~step_pulse[2]) );
  127.         assign  drq_pospulse = (  drq_pulse[1] & ( ~drq_pulse[2]) );
  128.  
  129.         always @(posedge fclk,negedge rst_n)
  130.         begin
  131.                 if( !rst_n )
  132.                         turbo_state <= 1'b0;
  133.                 else
  134.                 begin
  135.                         if( drq_pospulse )
  136.                                 turbo_state <= 1'b0;
  137.                         else if( step_pospulse )
  138.                                 turbo_state <= 1'b1;
  139.                 end
  140.         end
  141.  
  142.  
  143.  
  144.         assign vgclk_strobe7 = (vgclk_div7[2:1] == 2'b11); // 28/7=4MHz freq strobe
  145.  
  146.         always @(posedge fclk)
  147.         begin
  148.                 if( vgclk_strobe7 )
  149.                         vgclk_div7 <= 3'd0;
  150.                 else
  151.                         vgclk_div7 <= vgclk_div7 + 3'd1;
  152.         end
  153.  
  154.         always @(posedge fclk)
  155.         begin
  156.                 if( vgclk_strobe7 )
  157.                 begin
  158.                         vgclk_div4[0] <= ~vgclk_div4[1];
  159.  
  160.                         if( turbo_state )
  161.                                 vgclk_div4[1] <= ~vgclk_div4[1];
  162.                         else
  163.                                 vgclk_div4[1] <= vgclk_div4[0];
  164.                 end
  165.         end
  166.  
  167.         assign vg_clk = vgclk_div4[1];
  168.  
  169.  
  170.         // input/output for TR-DOS port #FF
  171.  
  172.         always @(posedge zclk, negedge rst_n) // CHANGE IF GO TO THE positive/negative strobes instead of zclk!
  173.         begin
  174.                 if( !rst_n )
  175.                         vg_res_n <= 1'b0;
  176.                 else if( vg_wrFF )
  177.                         { vg_side, vg_hrdy, vg_res_n, vg_a } <= { (~din[4]),din[3],din[2],din[1:0] };
  178.         end
  179.  
  180.         always @(posedge zclk)
  181.         begin
  182.                 intrq_sync[1:0] <= {intrq_sync[0],vg_irq};
  183.                 drq_sync[1:0] <= {drq_sync[0],vg_drq};
  184.         end
  185.  
  186.         assign intrq = intrq_sync[1];
  187.         assign drq   =   drq_sync[1];
  188.  
  189.  
  190.  
  191.  
  192.         // write precompensation
  193.         // delay times are as in WRDELAY_* parameters, vg_wrd width is always 7 clocks
  194.  
  195.         always @(posedge fclk)
  196.         begin
  197.                   sl_sync[1:0] <= {   sl_sync[0],   vg_sl   };
  198.                   sr_sync[1:0] <= {   sr_sync[0],   vg_sr   };
  199.                 tr43_sync[1:0] <= { tr43_sync[0],   vg_tr43 };
  200.                   wd_sync[2:0] <= {   wd_sync[1:0], vg_wd   };
  201.         end
  202.  
  203.         assign   sl =   sl_sync[1]; // just state signals
  204.         assign   sr =   sr_sync[1]; //
  205.         assign tr43 = tr43_sync[1]; //
  206.  
  207.         assign   wd =   wd_sync[1] & (~wd_sync[2]); // strobe: beginning of vg_wd
  208.  
  209.  
  210.         // make delay
  211.         always @(posedge fclk)
  212.         begin
  213.                 if( wd )
  214.                         case( {sl, tr43, sr} )
  215.                         3'b100:  // shift left, outer tracks
  216.                                 wrdelay_cnt <= WRDELAY_OUTER_LEFT;
  217.                         3'b001:  // shift right, outer tracks
  218.                                 wrdelay_cnt <= WRDELAY_OUTER_RIGHT;
  219.                         3'b110:  // shift left, inner tracks
  220.                                 wrdelay_cnt <= WRDELAY_INNER_LEFT;
  221.                         3'b011:  // shift right, inner tracks
  222.                                 wrdelay_cnt <= WRDELAY_INNER_RIGHT;
  223.                         default: // no shift
  224.                                 wrdelay_cnt <= WRDELAY_STANDARD;
  225.                         endcase
  226.                 else if( !delay_end )
  227.                         wrdelay_cnt <= wrdelay_cnt - 4'd1;
  228.         end
  229.  
  230.         assign delay_end = (wrdelay_cnt==4'd0);
  231.  
  232.  
  233.         // make vg_wdr impulse after a delay
  234.  
  235.         always @(posedge fclk)
  236.                 if( wrwidth_ena )
  237.                 begin
  238.                         if( wd )
  239.                                 wrwidth_cnt <= 4'd0;
  240.                         else
  241.                                 wrwidth_cnt <= wrwidth_cnt + 4'd1;
  242.                 end
  243.  
  244.         assign wrwidth_ena = wd | ( delay_end & (~wrwidth_cnt[3]) );
  245.  
  246.         always @(posedge fclk)
  247.                 vg_wrd <= | wrwidth_cnt[2:0]; // only 7 clocks is the lendth of vg_wrd
  248.  
  249.  
  250.  
  251.  
  252. /*      fapch_counter dpll
  253.         (
  254.                 .fclk   (fclk   ),
  255.  
  256.                 .rdat_n (rdat_n ),
  257.  
  258.                 .vg_rclk(vg_rclk),
  259.                 .vg_rawr(vg_rawr)
  260.         );
  261. */
  262.  
  263.         fapch_zek     dpll
  264.         (
  265.                 .fclk   (fclk   ),
  266.  
  267.                 .rdat_n (rdat_n ),
  268.  
  269.                 .vg_rclk(vg_rclk),
  270.                 .vg_rawr(vg_rawr)
  271.         );
  272.  
  273.  
  274.  
  275.  
  276. endmodule
  277.  
  278.