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. // generates horizontal sync, blank and video start strobe, horizontal window
  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. //
  25. // =\                  /=========||...
  26. // ==\                /==========||...
  27. // ====---     -------===========||...
  28. //    |  \   / |      |
  29. //    |   ---  |      |
  30. //    |  |   | |      |
  31. //    0  t1  | t3     t4
  32. //           t2
  33. // at 0, video ends and blank begins
  34. //    t1 = 10 clocks (@7MHz), sync begins
  35. // t2-t1 = 33 clocks
  36. // t3-t2 = 41 clocks, then video starts
  37. //
  38. // repetition period = 448 clocks
  39.  
  40. `include "../include/tune.v"
  41.  
  42. module video_sync_h(
  43.  
  44.         input  wire        clk,
  45.  
  46.         input  wire        init, // one-pulse strobe read at cend==1, initializes phase
  47.                                  // this is mainly for phasing with CPU clock 3.5/7 MHz
  48.                                  // still not used, but this may change anytime
  49.  
  50.         input  wire        cend,     // working strobes from DRAM controller (7MHz)
  51.         input  wire        pre_cend,
  52.  
  53.  
  54.         // modes inputs
  55.         input  wire        mode_atm_n_pent,
  56.         input  wire        mode_a_text,
  57.  
  58.         input  wire [ 1:0] modes_raster,
  59.         input  wire        mode_contend_type,
  60.  
  61.         output reg         hblank,
  62.         output reg         hsync,
  63.  
  64.         output reg         line_start,  // 1 video cycle prior to actual start of visible line
  65.         output reg         hsync_start, // 1 cycle prior to beginning of hsync: used in frame sync/blank generation
  66.                                         // these signals coincide with cend
  67.  
  68.         output reg         hint_start, // horizontal position of INT start, for fine tuning
  69.  
  70.         output reg         scanin_start,
  71.  
  72.         input  wire        vpix,
  73.         output reg         hpix, // marks gate during which pixels are outting
  74.  
  75.         output reg         contend, // for 48k/128k CPU contention
  76.  
  77.         output reg         border_sync, // for 48k/128k 4t border emulation
  78.  
  79.                                         // these signals turn on and turn off 'go' signal
  80.         output reg         fetch_start, // 18 cycles earlier than hpix, coincide with cend
  81.         output reg         fetch_end    // --//--
  82.  
  83. );
  84.  
  85.  
  86.         localparam HBLNK_BEG = 9'd00;
  87.         localparam HSYNC_BEG = 9'd10;
  88.         localparam HSYNC_END = 9'd43;
  89.         localparam HBLNK_END = 9'd88;
  90.  
  91.         // pentagon (x256)
  92.         localparam HPIX_BEG_PENT = 9'd140; // 52 cycles from line_start to pixels beginning
  93.         localparam HPIX_END_PENT = 9'd396;
  94.  
  95.         // atm (x320)
  96.         localparam HPIX_BEG_ATM = 9'd108; // 52 cycles from line_start to pixels beginning
  97.         localparam HPIX_END_ATM = 9'd428;
  98.  
  99.  
  100.         localparam FETCH_FOREGO = 9'd18; // consistent with older go_start in older fetch.v:
  101.                                          // actual data starts fetching 2 dram cycles after
  102.                                          // 'go' goes to 1, screen output starts another
  103.                                          // 16 cycles after 1st data bundle is fetched
  104.  
  105.  
  106.         localparam SCANIN_BEG = 9'd88; // when scan-doubler starts pixel storing
  107.  
  108.  
  109.         localparam HINT_BEG      = 9'd2;
  110.         localparam HINT_BEG_48K  = 9'd126;
  111.         localparam HINT_BEG_128K = 9'd130;
  112.  
  113.  
  114.         localparam HPERIOD_224 = 9'd448;
  115.         localparam HPERIOD_228 = 9'd456;
  116.  
  117.  
  118.         localparam CONTEND_START = 9'd127; // fixed for correct contend phase: coincides with positive edge of z80 clock
  119.         //localparam CONTEND_START_48K  = 9'd132;
  120.         //localparam CONTEND_START_128K = 9'd132;
  121.  
  122.  
  123.         localparam BORDER_PHASE = 3'd4;
  124.  
  125.  
  126.         reg [8:0] hcount;
  127.  
  128.         reg [8:0] contend_ctr;
  129.  
  130.         // for simulation only
  131.         //
  132.         initial
  133.         begin
  134.                 hcount = 9'd0;
  135.                 hblank = 1'b0;
  136.                 hsync = 1'b0;
  137.                 line_start = 1'b0;
  138.                 hsync_start = 1'b0;
  139.                 hpix = 1'b0;
  140.         end
  141.  
  142.  
  143.  
  144.  
  145.         always @(posedge clk) if( cend )
  146.         begin
  147.             if(  init || hcount==( (modes_raster==2'b11) ? (HPERIOD_228-9'd1) : (HPERIOD_224-9'd1) )  )
  148.                 hcount <= 9'd0;
  149.             else
  150.                 hcount <= hcount + 9'd1;
  151.         end
  152.  
  153.  
  154.  
  155.         always @(posedge clk) if( cend )
  156.         begin
  157.                 if( hcount==HBLNK_BEG )
  158.                         hblank <= 1'b1;
  159.                 else if( hcount==HBLNK_END )
  160.                         hblank <= 1'b0;
  161.  
  162.  
  163.                 if( hcount==HSYNC_BEG )
  164.                         hsync <= 1'b1;
  165.                 else if( hcount==HSYNC_END )
  166.                         hsync <= 1'b0;
  167.         end
  168.  
  169.  
  170.         always @(posedge clk)
  171.         begin
  172.                 if( pre_cend )
  173.                 begin
  174.                         if( hcount==HSYNC_BEG )
  175.                                 hsync_start <= 1'b1;
  176.  
  177.                         if( hcount==HBLNK_END )
  178.                                 line_start <= 1'b1;
  179.  
  180.                         if( hcount==SCANIN_BEG )
  181.                                 scanin_start <= 1'b1;
  182.  
  183.                 end
  184.                 else
  185.                 begin
  186.                         hsync_start  <= 1'b0;
  187.                         line_start   <= 1'b0;
  188.                         scanin_start <= 1'b0;
  189.                 end
  190.         end
  191.  
  192.  
  193.  
  194.         wire fetch_start_time, fetch_start_condition;
  195.         wire fetch_end_condition;
  196.  
  197.         reg [3:0] fetch_start_wait;
  198.  
  199.  
  200.         assign fetch_start_time = (mode_atm_n_pent                  ?
  201.                                   (HPIX_BEG_ATM -FETCH_FOREGO-9'd4) :
  202.                                   (HPIX_BEG_PENT-FETCH_FOREGO-9'd4) ) == hcount;
  203.  
  204.         always @(posedge clk) if( cend )
  205.                 fetch_start_wait[3:0] <= { fetch_start_wait[2:0], fetch_start_time };
  206.  
  207.         assign fetch_start_condition = mode_a_text ? fetch_start_time  : fetch_start_wait[3];
  208.  
  209.         always @(posedge clk)
  210.         if( pre_cend && fetch_start_condition )
  211.                 fetch_start <= 1'b1;
  212.         else
  213.                 fetch_start <= 1'b0;
  214.  
  215.  
  216.  
  217.  
  218.         assign fetch_end_time = (mode_atm_n_pent             ?
  219.                                 (HPIX_END_ATM -FETCH_FOREGO) :
  220.                                 (HPIX_END_PENT-FETCH_FOREGO) ) == hcount;
  221.  
  222.         always @(posedge clk)
  223.         if( pre_cend && fetch_end_time )
  224.                 fetch_end <= 1'b1;
  225.         else
  226.                 fetch_end <= 1'b0;
  227.  
  228.  
  229.  
  230.  
  231.  
  232.         always @(posedge clk)
  233.         begin
  234.                 if( pre_cend && hcount==( modes_raster[1] ? (modes_raster[0] ? HINT_BEG_128K : HINT_BEG_48K) : HINT_BEG ) )
  235.                         hint_start <= 1'b1;
  236.                 else
  237.                         hint_start <= 1'b0;
  238.         end
  239.  
  240.  
  241.         always @(posedge clk) if( cend )
  242.         begin
  243.                 if( hcount==(mode_atm_n_pent ? HPIX_BEG_ATM : HPIX_BEG_PENT) )
  244.                         hpix <= 1'b1;
  245.                 else if( hcount==(mode_atm_n_pent ? HPIX_END_ATM : HPIX_END_PENT) )
  246.                         hpix <= 1'b0;
  247.         end
  248.  
  249.  
  250.  
  251.         // contention generator
  252.         initial
  253.                 contend_ctr <=9'h100;
  254.         //
  255.         always @(posedge clk) if( cend )
  256.         begin
  257.                 if( hcount == CONTEND_START )
  258.                         contend_ctr <= 9'd0;
  259.                 else if( !contend_ctr[8] )
  260.                         contend_ctr <= contend_ctr + 9'd1;
  261.         end
  262.         //
  263.         //
  264.         always @(posedge clk) if( cend )
  265.         begin
  266.                 if( contend_ctr[8] || !vpix )
  267.                         contend <= 1'b0;
  268.                 else if( !mode_contend_type )
  269.                 // 48k type contention
  270.                 case( contend_ctr[3:1] )
  271.                         3'd6,
  272.                         3'd7:    contend <= 1'b0;
  273.                         default: contend <= 1'b1;
  274.                 endcase
  275.                 else
  276.                 // +2a/+3 type contention
  277.                 case( contend_ctr[3:1] )
  278.                         3'd1:    contend <= 1'b0;
  279.                         default: contend <= 1'b1;
  280.                 endcase
  281.                 //
  282.                 // warning! probably +2a/+3 contention pattern is incorrect, it begins with 1 cycle contention but probably should end
  283.                 //  with one extra contention cycle. Anyway this is left as TODO.
  284.                 //
  285.         end
  286.  
  287.  
  288.  
  289.         // border sync signal gen
  290.         always @(posedge clk)
  291.         if( pre_cend && hcount[2:0]==BORDER_PHASE )
  292.                 border_sync <= 1'b1;
  293.         else
  294.                 border_sync <= 1'b0;
  295.                
  296.  
  297.  
  298. endmodule
  299.  
  300.