Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. `include "../include/tune.v"
  2.  
  3. // PentEvo project (c) NedoPC 2008-2009
  4. //
  5. // fetches and outs video data
  6. //
  7. // currently only 256x192 standard zx and p16c modes supported
  8. //
  9. //
  10.  
  11. module fetch(
  12.  
  13.         input clk,
  14.  
  15.  
  16.         input cend,
  17.  
  18.         input line_start,
  19.         input vpix,       // hpix not needed! fetch.v has its own count from line_start to the hpix window opening
  20.  
  21.         input int_start,  // used as initializer for counters
  22.  
  23.  
  24.  
  25.         input [1:0] vmode, // 2'b00 - standard ZX, 2'b01 - hardware multicolor, 2'b1x - p16c
  26.  
  27.         input screen, // screen 0 (pg5) or screen 1 (pg7)
  28.  
  29.  
  30.         // controlling data fetch (go to dram/arbiter.v)
  31.         output reg [20:0] video_addr,
  32.         input [15:0] video_data,
  33.         input video_strobe,
  34.         input video_next,
  35.         output [1:0] bw,
  36.         output reg go,
  37.         output [7:0] attr,
  38.  
  39.         output [5:0] pixel
  40. );
  41.  
  42.  
  43.         localparam START_FETCH = 6'd36;
  44.  
  45.  
  46. // begin data fetching 16 cycles before actual start if hpix, (52-16)=36 cycles after line_start.
  47.  
  48.         reg [15:0] fbuf [0:3]; // reading memory data
  49.  
  50.         reg [7:0] shift [0:7]; // shifting out pixel data
  51.  
  52.  
  53.  
  54.         reg [7:0] vcnt; // vertical line counter (0-191)
  55.  
  56.         reg [3:0] hcnt; // horizontal word counter (0-15)
  57.         reg [1:0] dcnt; // displacement or pix/attr counter
  58.         reg [1:0] ddcnt; // dcnt saved for data reception
  59.  
  60.  
  61.         reg [5:0] scnt; // start-fetch counter
  62.  
  63.         wire wordsync; // synchronize words output: every 16th dram cycle
  64.         reg [3:0] wcnt; // word (16 cycles) counter
  65.  
  66.         reg [4:0] fcnt; // fetches counter; counts from 0 to 16 as each 16cycles passes, at the end stops fetching by issuing go_end
  67.  
  68.  
  69.         wire go_start,go_end;
  70.  
  71.  
  72.         reg [3:0] pixnumber; // pixel number; 0 - leftmost, 15 - rightmost
  73.  
  74.  
  75.         wire flash;
  76.         reg [4:0] flashctr;
  77.  
  78.  
  79.         reg [3:0] zxcolor;
  80.  
  81.         assign attr = attrbyte;
  82.  
  83.         initial
  84.         begin
  85.                 go = 1'b0;
  86.  
  87.                 vcnt = 8'd0;
  88.                 hcnt = 4'd0;
  89.                 dcnt = 2'd0;
  90.                 ddcnt = 2'd0;
  91.                 scnt = 6'd0;
  92.                 wcnt = 4'd0;
  93.                 fcnt = 5'd0;
  94.                 pixnumber = 4'd0;
  95.                 flashctr = 5'd0;
  96.         end
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.         // flash generator
  108.         always @(posedge clk) if( int_start )
  109.         begin
  110.                 flashctr <= flashctr + 5'd1;
  111.         end
  112.         assign flash = flashctr[4];
  113.  
  114.  
  115.         // fetchmode generator
  116.  
  117.         assign bw = vmode[1] ? 2'b01 : 2'b00;
  118.  
  119.  
  120.  
  121.  
  122.         // vertical counter
  123.         always @(posedge clk)
  124.         begin
  125.                 if( int_start )
  126.                         vcnt <= 8'hFF;
  127.                 else if( line_start && vpix ) // line-start will also happen in the first pixel line, so we initialize counter with 0xFF
  128.                         vcnt <= vcnt + 8'h01;
  129.         end
  130.  
  131.  
  132.         // start-fetch counter
  133.         always @(posedge clk) if( cend )
  134.         begin
  135.                 if( line_start && vpix )
  136.                         scnt <= (START_FETCH - 6'd2);
  137.                 else if( scnt!=6'd0)
  138.                         scnt <= scnt - 6'd1;
  139.         end
  140.         assign go_start = (scnt==6'd1) & cend; // start go signal 1 cycle before actual data will begin to fetch
  141.  
  142.  
  143.         //wordsync generation and synchronizing
  144.         always @(posedge clk) if( cend )
  145.         begin
  146.                 if( go_start )
  147.                         wcnt <= 4'd0;
  148.                 else
  149.                         wcnt <= wcnt + 4'd1;
  150.         end
  151.         assign wordsync = (wcnt==4'd1) & cend;
  152.  
  153.         // fetch counter
  154.         always @(posedge clk)
  155.         begin
  156.                 if( go_start )
  157.                         fcnt <= 5'd0;
  158.                 else if( wordsync && (~fcnt[4]) )
  159.                         fcnt <= fcnt + 5'd1;
  160.         end
  161.         assign go_end = fcnt[4] & (wcnt==4'd15) & cend;
  162.  
  163.  
  164.         // go
  165.         always @(posedge clk)
  166.                 if( go_start )
  167.                         go <= 1'b1;
  168.                 else if( go_end )
  169.                         go <= 1'b0;
  170.  
  171.  
  172.  
  173.         // horizontal address counters: init and increment
  174.         always @(posedge clk)
  175.         begin
  176.                 if( line_start ) // initialize counters
  177.                 begin
  178.                         hcnt <= 4'd0;
  179.                         dcnt <= 2'd0;
  180.                 end
  181.                 else if( video_next )
  182.                 begin
  183.                         ddcnt <= dcnt;
  184.  
  185.                         dcnt <= dcnt + 2'd1;
  186.  
  187.                         if( !vmode[1] ) // normal ZX standard
  188.                         begin
  189.                                 if( dcnt[0] )
  190.                                         hcnt <= hcnt + 4'd1;
  191.                         end
  192.                         else // vmode[1] - p16c mode
  193.                         begin
  194.                                 if( dcnt==2'd3 )
  195.                                         hcnt <= hcnt + 4'd1;
  196.                         end
  197.                 end
  198.         end
  199.  
  200.  
  201.         // store fetched data
  202.         always @(posedge clk) if( video_strobe )
  203.         begin
  204.                 if( !vmode[1] ) // ZX mode
  205.                         fbuf[{1'b0,ddcnt[0]}] <= video_data;
  206.                 else // p16c mode
  207.                         fbuf[ddcnt[1:0]] <= video_data;
  208.         end
  209.  
  210.  
  211.         // sequence video addresses
  212.         always @*
  213.         begin
  214.                 video_addr[20:14] = { 6'b000001,screen }; // common part of address
  215.  
  216.                 if( !vmode[1] ) // ZX mode
  217.                 begin
  218.                         if( !dcnt[0] ) // pixel addr
  219.                                 video_addr[13:0] = { 2'b10, vcnt[7:6], vcnt[2:0], vcnt[5:3], hcnt[3:0] };
  220.                         else // attr addr
  221.                         begin
  222.                                 if( !vmode[0] ) // normal ZX
  223.                                         video_addr[13:0] = { 5'b10110, vcnt[7:3], hcnt[3:0] };
  224.                                 else // hardware multicolor
  225.                                         video_addr[13:0] = { 2'b11, vcnt[7:6], vcnt[2:0], vcnt[5:3], hcnt[3:0] };
  226.                         end
  227.                 end
  228.                 else // p16c mode
  229.                         begin
  230.                                 video_addr[13:0] = { dcnt[0], dcnt[1], vcnt[7:6], vcnt[2:0], vcnt[5:3], hcnt[3:0] };
  231.                         end
  232.         end
  233.  
  234.         // pass read data to pixel engine
  235.         always @(posedge clk) if( wordsync )
  236.         begin
  237.                 shift[0] <= fbuf[0][15:8];
  238.                 shift[1] <= fbuf[0][7:0];
  239.                 shift[2] <= fbuf[1][15:8];
  240.                 shift[3] <= fbuf[1][7:0];
  241.                 shift[4] <= fbuf[2][15:8];
  242.                 shift[5] <= fbuf[2][7:0];
  243.                 shift[6] <= fbuf[3][15:8];
  244.                 shift[7] <= fbuf[3][7:0];
  245.         end
  246.  
  247.         // count pixels to be out
  248.         always @(posedge clk) if( cend )
  249.                 if( wordsync )
  250.                         pixnumber <= 4'd0;
  251.                 else
  252.                         pixnumber <= pixnumber + 4'd1;
  253.  
  254.  
  255.  
  256.  
  257.  
  258.         // out pixels
  259.  
  260.         reg [7:0] pixbyte,attrbyte;
  261.  
  262.         reg [3:0] pix0,pix1;
  263.  
  264.  
  265.         always @*
  266.         begin
  267.                 attrbyte = shift[ { 2'b01, pixnumber[3] } ][7:0];
  268.                 pix0 = { attrbyte[6],attrbyte[5:3] };
  269.                 pix1 = { attrbyte[6],attrbyte[2:0] };
  270.  
  271.                 if( !vmode[1] ) // ZX mode
  272.                 begin
  273.                         // attribute is taken
  274.  
  275.                         // pixels
  276.                         pixbyte = shift[ { 2'b00, pixnumber[3] } ][7:0];
  277.  
  278.                         zxcolor = ( pixbyte[(~pixnumber[2:0])] ^ (flash & attrbyte[7]) ) ? pix1 : pix0;
  279.                 end
  280.                 else // p16c mode
  281.                 begin
  282.                         pixbyte = shift[ { pixnumber[2:1], pixnumber[3] } ][7:0];
  283.  
  284.                         zxcolor = pixnumber[0] ? { pixbyte[7],pixbyte[5:3] } : { pixbyte[6],pixbyte[2:0] };
  285.                 end
  286.         end
  287.  
  288.         // red
  289.         assign pixel[5:4] = zxcolor[1] ? ( zxcolor[3] ? 2'b11 : 2'b10 ) : 2'b00;
  290.         // green
  291.         assign pixel[3:2] = zxcolor[2] ? ( zxcolor[3] ? 2'b11 : 2'b10 ) : 2'b00;
  292.         // blue
  293.         assign pixel[1:0] = zxcolor[0] ? ( zxcolor[3] ? 2'b11 : 2'b10 ) : 2'b00;
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301. endmodule
  302.  
  303.  
  304.